Index: /branches/rel4/psLib/.cvsignore
===================================================================
--- /branches/rel4/psLib/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/.cvsignore	(revision 3057)
@@ -0,0 +1,6 @@
+bin
+lib
+man
+psLib.kdevelop.*
+docs
+testbin
Index: /branches/rel4/psLib/psLib.kdevelop
===================================================================
--- /branches/rel4/psLib/psLib.kdevelop	(revision 3057)
+++ /branches/rel4/psLib/psLib.kdevelop	(revision 3057)
@@ -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/>
+    </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/rel4/psLib/psLib.kdevses
===================================================================
--- /branches/rel4/psLib/psLib.kdevses	(revision 3057)
+++ /branches/rel4/psLib/psLib.kdevses	(revision 3057)
@@ -0,0 +1,51 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE KDevPrjSession>
+<KDevPrjSession>
+ <DocsAndViews NumberOfDocuments="8" >
+  <Doc0 NumberOfViews="1" URL="file:/home/desonia/psLib/test/fileUtils/tst_psFits.c" >
+   <View0 Type="Source" />
+  </Doc0>
+  <Doc1 NumberOfViews="1" URL="file:/home/desonia/psLib/src/fileUtils/psFits.h" >
+   <View0 Type="Source" />
+  </Doc1>
+  <Doc2 NumberOfViews="1" URL="file:/home/desonia/psLib/src/fileUtils/psFits.c" >
+   <View0 Type="Source" />
+  </Doc2>
+  <Doc3 NumberOfViews="1" URL="file:/home/desonia/psLib/src/image/psImage.h" >
+   <View0 Type="Source" />
+  </Doc3>
+  <Doc4 NumberOfViews="1" URL="file:/home/desonia/psLib/src/image/psImageIO.c" >
+   <View0 Type="Source" />
+  </Doc4>
+  <Doc5 NumberOfViews="1" URL="file:/home/desonia/psLib/src/fileUtils/psFileUtilsErrors.dat" >
+   <View0 Type="Source" />
+  </Doc5>
+  <Doc6 NumberOfViews="1" URL="file:/home/desonia/psLib/src/image/psImageErrors.dat" >
+   <View0 Type="Source" />
+  </Doc6>
+  <Doc7 NumberOfViews="1" URL="file:/home/desonia/psLib/src/sysUtils/psLogMsg.h" >
+   <View0 line="36" Type="Source" />
+  </Doc7>
+ </DocsAndViews>
+ <pluginList>
+  <kdevbookmarks>
+   <bookmarks>
+    <bookmark url="/home/desonia/psLib/src/fileUtils/psFits.c" >
+     <mark line="146" />
+    </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="" />
+   <calltree path="" params="" />
+   <kcachegrind path="" />
+  </kdevvalgrind>
+  <kdevdebugger>
+   <breakpointList/>
+  </kdevdebugger>
+ </pluginList>
+</KDevPrjSession>
Index: /branches/rel4/psLib/src/.cvsignore
===================================================================
--- /branches/rel4/psLib/src/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/src/.cvsignore	(revision 3057)
@@ -0,0 +1,1 @@
+DoxygenLog
Index: /branches/rel4/psLib/src/Doxyfile
===================================================================
--- /branches/rel4/psLib/src/Doxyfile	(revision 3057)
+++ /branches/rel4/psLib/src/Doxyfile	(revision 3057)
@@ -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.3-R4
+
+# 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/rel4/psLib/src/Makefile
===================================================================
--- /branches/rel4/psLib/src/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/Makefile	(revision 3057)
@@ -0,0 +1,230 @@
+###############################################################################
+##
+##  Makefile:  psLib
+##
+##  $Revision: 1.19 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-12-10 02:50:14 $
+##
+##  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 fileUtils
+
+TARGET_DYNAMIC = libpslib.$(DLL)
+TARGET_STATIC = libpslib.a
+
+# Define the installation targets
+
+INSTALLTARGETS = installSysUtils installCollections installImage installDataManip installAstronomy installFileUtils
+
+# Define the clean up targets
+
+CLEANTARGETS = cleanSysUtils cleanCollections cleanImage cleanDataManip cleanAstronomy cleanFileUtils
+
+CLEANDEPTARGETS = cleandepSysUtils cleandepCollections cleandepImage cleandepDataManip cleandepAstronomy cleandepFileUtils
+
+# Define the distribution clean up targets
+
+DISTCLEANTARGETS = distcleanSysUtils distcleanCollections distcleanImage distcleanDataManip distcleanAstronomy distcleanFileUtils
+
+# 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
+
+fileUtils:
+	$(MAKE) --directory=fileUtils 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
+
+installFileUtils:
+	$(MAKE) --directory=fileUtils 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
+
+cleanFileUtils:
+	$(MAKE) --directory=fileUtils 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
+
+cleandepFileUtils:
+	$(MAKE) --directory=fileUtils 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
+
+distcleanFileUtils:
+	$(MAKE) --directory=fileUtils 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:
+	etags `find . \( -name \*.[chy] \) -print`
+
+# List of PHONY targets with make file
+.PHONY:  sysUtils collections image dataManip astronomy fileUtils
Index: /branches/rel4/psLib/src/Makefile.Globals
===================================================================
--- /branches/rel4/psLib/src/Makefile.Globals	(revision 3057)
+++ /branches/rel4/psLib/src/Makefile.Globals	(revision 3057)
@@ -0,0 +1,117 @@
+
+################################################################################
+##
+##  Makefile:  Globals
+##
+##  Assumptions:    Variable "prefix" already defined
+##
+##  $Revision: 1.38 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-04 02:34:56 $
+##
+##  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 TIME_CONFIG_FILE
+    export TIME_CONFIG_FILE = $(prefix)/config/psTime.config
+endif
+
+ifndef PS_LIB_VERSION
+    export PS_LIB_VERSION = rel4
+endif
+
+ifndef sladir
+    export sladir = /usr/local/star
+endif
+
+ifndef xml2config
+    export xml2config = `which xml2-config`
+endif
+
+SLA_LINK := $(shell $(sladir)/bin/sla_link)
+XML2_LINK := $(shell $(xml2config) --libs)
+
+XML2_CFLAGS := $(shell $(xml2config) --cflags)
+
+# 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) $(XML2_CFLAGS)
+
+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.
+
+EXTLIBS := -lcfitsio -lgsl -lgslcblas -lfftw3f -L$(sladir)/lib $(SLA_LINK) $(XML2_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/rel4/psLib/src/astro/psCoord.c
===================================================================
--- /branches/rel4/psLib/src/astro/psCoord.c	(revision 3057)
+++ /branches/rel4/psLib/src/astro/psCoord.c	(revision 3057)
@@ -0,0 +1,682 @@
+/** @file  psCoord.c
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.46 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-14 23:27:55 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psType.h"
+#include "psCoord.h"
+#include "psMemory.h"
+#include "psTime.h"
+#include "psConstants.h"
+#include "psError.h"
+#include "psLogMsg.h"
+#include "psAstronomyErrors.h"
+#include <math.h>
+#include <float.h>
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+static void planeTransformFree(psPlaneTransform *pt)
+{
+    psFree(pt->x);
+    psFree(pt->y);
+}
+
+psPlaneTransform* psPlaneTransformAlloc(psS32 n1, psS32 n2)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n1, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n2, NULL);
+
+    psPlaneTransform *pt = psAlloc(sizeof(psPlaneTransform));
+    pt->x = psDPolynomial2DAlloc(n1, n2, PS_POLYNOMIAL_ORD);
+    pt->y = psDPolynomial2DAlloc(n1, n2, PS_POLYNOMIAL_ORD);
+
+    p_psMemSetDeallocator(pt, (psFreeFcn) planeTransformFree);
+    return(pt);
+}
+
+psPlane* psPlaneTransformApply(psPlane* out,
+                               const psPlaneTransform* transform,
+                               const psPlane* coords)
+{
+    PS_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(transform->x, NULL);
+    PS_PTR_CHECK_NULL(transform->y, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial2DEval(
+                 transform->x,
+                 coords->x,
+                 coords->y
+             );
+    out->y = psDPolynomial2DEval(
+                 transform->y,
+                 coords->x,
+                 coords->y
+             );
+    return (out);
+}
+
+static void planeDistortFree(psPlaneDistort *pt)
+{
+    psFree(pt->x);
+    psFree(pt->y);
+}
+
+psPlaneDistort* psPlaneDistortAlloc(psS32 n1, psS32 n2, psS32 n3, psS32 n4)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n1, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n2, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n3, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n4, NULL);
+
+    psPlaneDistort *pt = psAlloc(sizeof(psPlaneDistort));
+    pt->x = psDPolynomial4DAlloc(n1, n2, n3, n4, PS_POLYNOMIAL_ORD);
+    pt->y = psDPolynomial4DAlloc(n1, n2, n3, n4, PS_POLYNOMIAL_ORD);
+
+    p_psMemSetDeallocator(pt, (psFreeFcn) planeDistortFree);
+    return(pt);
+}
+
+/******************************************************************************
+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_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(transform->x, NULL);
+    PS_PTR_CHECK_NULL(transform->y, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial4DEval(
+                 transform->x,
+                 coords->x,
+                 coords->y,
+                 color,
+                 magnitude
+             );
+    out->y = psDPolynomial4DEval(
+                 transform->y,
+                 coords->x,
+                 coords->y,
+                 color,
+                 magnitude
+             );
+    return (out);
+}
+
+/******************************************************************************
+alpha is LONGITUDE
+delta is LATITUDE
+ 
+    alphaP: Take the target pole in the source system; calculate its LONGITUDE
+     in the target system.  That longitude is alphaP.
+    DeltaP: Take the target pole in the source system; calculate its LATITUDE
+     in the target system.  That longitude is deltaP.
+    phiP:   This is the LONGITUDE of the ascending node in the target system.
+ *****************************************************************************/
+psSphereTransform* psSphereTransformAlloc(psF64 alphaP,
+        psF64 deltaP,
+        psF64 phiP)
+{
+    psSphereTransform* tmp = (psSphereTransform* ) psAlloc(sizeof(psSphereTransform));
+
+    tmp->cosDeltaP = cos(deltaP);
+    tmp->sinDeltaP = sin(deltaP);
+    tmp->alphaP = alphaP;
+    tmp->phiP = phiP;
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Private Function.
+ 
+piNormalize(): take an input angle in radians and convert it to the range 0:PI.
+ *****************************************************************************/
+psF32 piNormalize(psF32 angle)
+{
+    while (angle < FLT_EPSILON) {
+        angle+=M_PI;
+    }
+
+    while (angle >= M_PI) {
+        angle-=M_PI;
+    }
+    return(angle);
+}
+
+/******************************************************************************
+XXX: We convert Right Ascension angles to the range 0:PI.  Is that acceptable?
+XXX: Should we do something for Declination as well?
+ *****************************************************************************/
+psSphere* psSphereTransformApply(psSphere* out,
+                                 const psSphereTransform* transform,
+                                 const psSphere* coord)
+{
+    PS_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(coord, NULL);
+
+    if (out == NULL) {
+        out = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    psF64 alpha = coord->r;
+    psF64 delta = coord->d;
+    psF64 alphaMinusAlphaP = alpha - transform->alphaP;
+
+    psF64 eq55 = (sin(delta) * transform->cosDeltaP) -
+                 (cos(delta) * transform->sinDeltaP * sin(alphaMinusAlphaP));
+
+    psF64 eq56 = (cos(delta) * transform->cosDeltaP * sin(alphaMinusAlphaP)) +
+                 (sin(delta) * transform->sinDeltaP);
+
+    psF64 eq57 = cos(delta) * cos(alphaMinusAlphaP);
+
+    psF64 theta = asin(eq55);
+    psF64 phi = atan2(eq56, eq57) + transform->alphaP;
+
+
+    out->r = piNormalize(phi);
+    out->d = theta;
+
+    return(out);
+}
+
+psSphereTransform* psSphereTransformICRSToEcliptic(psTime *time)
+{
+    PS_PTR_CHECK_NULL(time, NULL);
+    psF64 MJD = psTimeToMJD(time);
+    struct tm *tmTime = psTimeToTM(time);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 alphaP = 0.0;
+    psF64 deltaP = DEG_TO_RAD(23.0) +
+                   SEC_TO_RAD(27.0) +
+                   MIN_TO_RAD(8.0) -
+                   (SEC_TO_RAD(46.845) * T) -
+                   (SEC_TO_RAD(0.0059) * T * T) +
+                   (SEC_TO_RAD(0.00181) * T * T * T);
+    psF64 phiP = 0.0;
+
+    psFree(tmTime);
+
+    // Don't neglect the minus sign on deltaP (bug 244):
+    return (psSphereTransformAlloc(alphaP, -deltaP, phiP));
+}
+
+
+psSphereTransform* psSphereTransformEclipticToICRS(psTime *time)
+{
+    PS_PTR_CHECK_NULL(time, NULL);
+    psF64 MJD = psTimeToMJD(time);
+    struct tm *tmTime = psTimeToTM(time);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 alphaP = 0.0;
+    psF64 deltaP = DEG_TO_RAD(23.0) +
+                   SEC_TO_RAD(27.0) +
+                   MIN_TO_RAD(8.0) -
+                   (SEC_TO_RAD(46.845) * T) -
+                   (SEC_TO_RAD(0.0059) * T * T) +
+                   (SEC_TO_RAD(0.00181) * T * T * T);
+    psF64 phiP = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+// XXX: This is bug 245: alphaP swaps with phiP from psSphereTransformGalaticToICRS()
+psSphereTransform* psSphereTransformICRSToGalatic(void)
+{
+    psF64 alphaP = DEG_TO_RAD(32.93192);
+    psF64 deltaP = DEG_TO_RAD(-62.87175);
+    psF64 phiP = DEG_TO_RAD(282.85948);
+
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+psSphereTransform* psSphereTransformGalaticToICRS(void)
+{
+    psF64 alphaP = DEG_TO_RAD(282.85948);
+    psF64 deltaP = DEG_TO_RAD(62.87175);
+    psF64 phiP = DEG_TO_RAD(32.93192);
+
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: Must apply scaling at the end.
+ *****************************************************************************/
+psPlane* psProject(const psSphere* coord,
+                   const psProjection* projection)
+{
+    PS_PTR_CHECK_NULL(coord, NULL);
+    PS_PTR_CHECK_NULL(projection, NULL);
+
+    psPlane* tmp = (psPlane* ) psAlloc(sizeof(psPlane));
+    if (projection->type == PS_PROJ_TAN) {
+
+        /*
+                // ********************************************
+                // From the ADD
+                // ********************************************
+                // psLogMsg(__func__, PS_LOG_WARN, "WARNING: psProject(): These projections don't work.");
+                // return(NULL);
+                psF32 sinTheta;
+                psF32 cosThetaCosPhi;
+                psF32 cosThetaSinPhi;
+         
+                sinTheta = (sin(coord->d) * sin(projection->D)) + 
+                           (cos(coord->d) * cos(projection->D) * (cos(coord->r - projection->R)));
+                cosThetaCosPhi = (sin(coord->d) * cos(projection->D)) - 
+                                 (cos(coord->d) * sin(projection->D) * (cos(coord->r - projection->R)));
+                cosThetaSinPhi = - cos(coord->d) * sin(coord->r - projection->R);
+         
+                tmp->x =  -cosThetaSinPhi / sinTheta;
+                tmp->y = cosThetaCosPhi / sinTheta;
+         
+        */
+        // ********************************************
+        // From the mathworks: http://mathworld.wolfram.com/GnomonicProjection.html
+        // delta_0 and phi_1 are the projection centers, not the point being projected.
+        // (delta_0, phi_1) == (projection->R, projection->D)
+        // ********************************************
+        psF32 cosC = (sin(projection->D) * sin(coord->d)) +
+                     (cos(projection->D) * cos(coord->d) * cos(coord->r - projection->R));
+        tmp->x = (cos(coord->d) * sin(coord->r - projection->R)) / cosC;
+        tmp->y = ((cos(projection->D) * sin(coord->d)) -
+                  (sin(projection->D) * cos(coord->d) * cos(coord->r - projection->R))) /
+                 cosC;
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        // psLogMsg(__func__, PS_LOG_WARN, "WARNING: psProject(): These projections don't work.");
+        // return(NULL);
+
+        tmp->x = cos(coord->d) * sin(coord->d);
+        tmp->y = -cos(coord->d) * 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(DEG_TO_RAD(45.0) + (0.5 * coord->r)));
+    } else if (projection->type == PS_PROJ_AIT) {
+        psF64 tmpF64  = PS_SQRT_F32(0.5 * (1.0 + (cos(coord->r) * cos(0.5 * coord->d))));
+        tmpF64 = 1.0 / tmpF64;
+        tmp->x = 2.0 * tmpF64 * cos(coord->r) * sin(0.5 * coord->d);
+        tmp->y = sin(coord->r) * tmpF64;
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_PAR");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_GLS");
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
+                projection->type);
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Waiting for algorithms.
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: Must apply scaling at the beginning.
+ *****************************************************************************/
+psSphere* psDeproject(const psPlane* coord,
+                      const psProjection* projection)
+{
+    PS_PTR_CHECK_NULL(coord, NULL);
+    PS_PTR_CHECK_NULL(projection, NULL);
+    //    psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): These projections don't work.");
+    //    return(NULL);
+    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) {
+        /*
+                // ********************************************
+                // From the ADD
+                // ********************************************
+                psF32 phi;
+                psF32 theta;
+                psF32 sinDelta;
+                psF32 cosDeltaCosAlphaMinusAlphaP;
+                psF32 cosDeltaSinAlphaMinusAlphaP;
+         
+                phi = atan2(-coord->y, coord->x);
+                R = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+                theta = atan(1.0 / R);
+         
+                sinDelta = (sin(theta) * sin(projection->D)) + 
+                           (cos(theta) * cos(projection->D) * cos(phi));
+                cosDeltaCosAlphaMinusAlphaP = 
+                           (sin(theta) * cos(projection->D)) - 
+                           (cos(theta) * sin(projection->D) * cos(phi));
+                cosDeltaSinAlphaMinusAlphaP = -cos(theta) * sin(phi);
+                tmp->d = asin(sinDelta);
+                tmp->r = atan2(cosDeltaSinAlphaMinusAlphaP, cosDeltaCosAlphaMinusAlphaP) + projection->R;
+        */
+        // ********************************************
+        // From the mathworks: http://mathworld.wolfram.com/GnomonicProjection.html
+        // delta_0 and phi_1 are the projection centers, not the point being projected.
+        // (delta_0, phi_1) == (projection->R, projection->D)
+        // XXX: figure out how to use the two-argument atan2() here.
+        // ********************************************
+        psF32 row = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+        psF32 C = atan(row);
+        tmp->d = asin((cos(C) * sin(projection->D)) +
+                      ((coord->y * sin(C) * cos(projection->D)) / row));
+        psF32 tmpAtan = atan((coord->x * sin(C)) /
+                             ((row * cos(projection->D) * cos(C)) -
+                              (coord->y * sin(projection->D) * sin(C))));
+        tmp->r = projection->R + tmpAtan;
+
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = atan2(-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 = PS_SQRT_F32(1.0 - chu1 - chu2);
+        tmp->d = 2.0 * atan2((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) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_PAR");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_GLS");
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
+                projection->type);
+    }
+
+    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_PTR_CHECK_NULL(position1, NULL);
+    PS_PTR_CHECK_NULL(position2, NULL);
+
+    if (position1->d >= DEG_TO_RAD(90.0)) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): position1->d is larger than 90 degrees.  Returning NULL.\n");
+        return(NULL);
+    }
+    if (position2->d >= DEG_TO_RAD(90.0)) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): position2->d is larger than 90 degrees.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    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(position1, &proj);
+        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 = RAD_TO_SEC(tmp->r);
+            tmp->d = RAD_TO_SEC(tmp->d);
+        } else if (unit == PS_ARCMIN) {
+            tmp->r = RAD_TO_MIN(tmp->r);
+            tmp->d = RAD_TO_MIN(tmp->d);
+        } else if (unit == PS_DEGREE) {
+            tmp->r = RAD_TO_DEG(tmp->r);
+            tmp->d = RAD_TO_DEG(tmp->d);
+        } else if (unit == PS_RADIAN) {}
+        else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psCoord_UNITS_UNKNOWN,
+                    unit);
+            psFree(tmp);
+            return(NULL);
+        }
+
+        return (tmp);
+    }
+
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+            PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN,
+            mode);
+    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_PTR_CHECK_NULL(position, NULL);
+    PS_PTR_CHECK_NULL(offset, NULL);
+
+    psPlane lin;
+    psSphere* tmp;
+    psProjection proj;
+    psF64 tmpR = 0.0;
+    psF64 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 = SEC_TO_RAD(offset->r);
+            tmpD = SEC_TO_RAD(offset->d);
+        } else if (unit == PS_ARCMIN) {
+            tmpR = MIN_TO_RAD(offset->r);
+            tmpD = MIN_TO_RAD(offset->d);
+        } else if (unit == PS_DEGREE) {
+            tmpR = DEG_TO_RAD(offset->r);
+            tmpD = DEG_TO_RAD(offset->d);
+        } else if (unit == PS_RADIAN) {
+            tmpR = offset->r;
+            tmpD = offset->d;
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psCoord_UNITS_UNKNOWN,
+                    unit);
+            return(NULL);
+        }
+
+        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);
+    }
+
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+            PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN,
+            mode);
+
+    return (NULL);
+}
+
+
+
+/******************************************************************************
+psSpherePrecess(coords, fromTime, toTime):
+ 
+XXX: Use static memory for tmpST.
+ *****************************************************************************/
+psSphere *psSpherePrecess(psSphere *coords,
+                          const psTime *fromTime,
+                          const psTime *toTime)
+{
+    psF64 fromMJD = psTimeToMJD(fromTime);
+    psF64 toMJD = psTimeToMJD(toTime);
+    psF64 T = (toMJD - fromMJD) / 36525.0;
+
+    psF64 alphaP = DEG_TO_RAD(90.0) - ((DEG_TO_RAD(0.6406161) * T) +
+                                       (DEG_TO_RAD(0.0000839) * T * T) +
+                                       (DEG_TO_RAD(0.000005) * T * T * T));
+
+    psF64 deltaP = (DEG_TO_RAD(0.5567530) * T) -
+                   (DEG_TO_RAD(0.0001185) * T * T) -
+                   (DEG_TO_RAD(0.0000116) * T * T * T);
+
+    psF64 phiP = DEG_TO_RAD(90.0) - ((DEG_TO_RAD(0.6406161) * T) +
+                                     (DEG_TO_RAD(0.0003041) * T * T) +
+                                     (DEG_TO_RAD(0.0000051) * T * T * T));
+
+    psSphereTransform *tmpST = psSphereTransformAlloc(alphaP, deltaP, phiP);
+
+    psSphere *out = psSphereTransformApply(NULL, tmpST, coords);
+
+    psFree(tmpST);
+
+    return(out);
+}
+
Index: /branches/rel4/psLib/src/astro/psCoord.h
===================================================================
--- /branches/rel4/psLib/src/astro/psCoord.h	(revision 3057)
+++ /branches/rel4/psLib/src/astro/psCoord.h	(revision 3057)
@@ -0,0 +1,326 @@
+/** @file  psCoord.h
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-08 18:23:54 $
+*
+*  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 alphaP;                    ///< Longitude of the target system pole in the source system
+    double cosDeltaP;                 ///< Cosine of target pole latitude in the source system
+    double sinDeltaP;                 ///< Sine of target pole latitude in the source system
+    double phiP;                      ///< Longitude of the ascending node in the target system
+}
+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;
+
+/** Allocates a psPlaneTransform transform.
+ *
+ *  @return psPlaneTransform*     resulting plane transform
+ */
+
+psPlaneTransform* psPlaneTransformAlloc(
+    psS32 n1,  ///< The order of the x term in the transform.
+    psS32 n2   ///< The order of the y term in the transform.
+);
+
+/** 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.
+);
+
+/** Allocates a psPlaneDistort transform.
+ *
+ *  @return psPlaneDistort*     resulting plane distort transform
+ */
+
+psPlaneDistort* psPlaneDistortAlloc(
+    psS32 n1,  ///< The order of the w term in the transform.
+    psS32 n2,  ///< The order of the x term in the transform.
+    psS32 n3,  ///< The order of the y term in the transform.
+    psS32 n4   ///< The order of the z term in the transform.
+);
+
+
+/** 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 alphaP,                      ///< north pole latitude
+    double deltaP,                      ///< north pole longitude?
+    double phiP                         ///< defines the longitude in the input system of the equatorial intersection between the two systems (e.g, the first point of Ares).
+);
+
+/** 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
+);
+
+psSphere *psSpherePrecess(psSphere *coords,
+                          const psTime *fromTime,
+                          const psTime *toTime);
+
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astro/psTime.c
===================================================================
--- /branches/rel4/psLib/src/astro/psTime.c	(revision 3057)
+++ /branches/rel4/psLib/src/astro/psTime.c	(revision 3057)
@@ -0,0 +1,1166 @@
+/** @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.  They use the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-17 20:47:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#include "psTime.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psImage.h"
+#include "psCoord.h"
+#include "psString.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+#include "psLookupTable.h"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+#ifndef TIME_CONFIG_FILE
+#define TIME_CONFIG_FILE "../../config/psTime.config"
+#pragma warning TIME_CONFIG_FILE was not defined in the makefile.
+#endif
+
+#define MAX_STRING_LENGTH 256
+
+/** 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
+
+                /** Time metadata read from config file */
+                static psMetadata *timeMetadata = NULL;
+
+/** Static function prototypes */
+static char *cleanString(char *inString, int sLen);
+static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
+psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables);
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+static 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;
+}
+
+/** 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. */
+static char* getToken(char **inString, char *delimiter, psParseErrorType *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 = PS_PARSE_ERROR_GENERAL;
+    }
+
+    return cleanToken;
+}
+
+/** Searches time tables in priority order and performs interpolation if input index value is within a table.
+ * If the index value is out of range, the status is set accordingly. */
+psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables)
+{
+    psU32 i = 0;
+    char *tableName = NULL;
+    psF64 result = 0.0;
+    psLookupTable *table = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+
+
+
+    // Check time metadata. Function call reports errors.
+    if(timeMetadata == NULL) {
+        if(!p_psTimeInit(TIME_CONFIG_FILE))
+            return 0.0;
+    }
+
+    // Search each table in priority order: ser7, eopc,finals
+    for(i=0; i<nTables; i++) {
+
+        // Get table from metadata
+        tableName = metadataTableNames[i];
+        tableMetadataItem = psMetadataLookup(timeMetadata, tableName);
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                    tableName);
+            return 0.0;
+        }
+        table = (psLookupTable*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(table,0.0);
+
+        // Attempt to interpolate table
+        *status = PS_LOOKUP_SUCCESS;
+        result = psLookupTableInterpolate(table, index, 2, status);
+        if(*status == PS_LOOKUP_SUCCESS) {
+            return result;
+        } else if(*status == PS_LOOKUP_ERROR) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME,
+                    tableName);
+            return 0.0;
+        }
+    }
+
+    return result;
+}
+
+bool p_psTimeInit(const char *fileName)
+{
+    bool foundTable = false;
+    char *tableDir = NULL;
+    char *tableNames = NULL;
+    char *namesPtr = NULL;
+    char *metadataNamesPtr = NULL;
+    char *tableName = NULL;
+    char *fullTableName = NULL;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 numTables = 0;
+    psU32 nFail = 0;
+    psVector *tablesFrom = NULL;
+    psVector *tablesTo = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psLookupTable *table = NULL;
+    psParseErrorType status = PS_PARSE_SUCCESS;
+    char metadataTableNames[4][MAX_STRING_LENGTH] = {"ser7", "eopc",  "finals", "tai"};
+
+
+    // Read time config file
+    timeMetadata = psMetadataParseConfig(timeMetadata, &nFail, fileName, true);
+    if(timeMetadata == NULL) {
+        return false;
+    } else if(nFail != 0) {
+        return false;
+    }
+
+    // Get number of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.n");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.n");
+        return false;
+    }
+    numTables = (psS32)metadataItem->data.S32;
+
+    // Get lower range of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.from");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.from");
+        return false;
+    }
+    tablesFrom = psVectorCopy(tablesFrom, metadataItem->data.V, PS_TYPE_F64);
+    if(tablesFrom->n != numTables) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_VECTOR, tablesFrom->n, numTables);
+        psFree(tablesFrom);
+        return false;
+    }
+
+    // Get upper range of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.to");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.to");
+        return false;
+    }
+    tablesTo = psVectorCopy(tablesTo, metadataItem->data.V, PS_TYPE_F64);
+    if(tablesTo->n != numTables) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_VECTOR, tablesTo->n, numTables);
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        return false;
+    }
+
+    // Get path to time data files
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.dir");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.dir");
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        return false;
+    }
+    tableDir = psStringCopy(metadataItem->data.V);
+
+    // Table file names
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.files");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.files");
+
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        psFree(tableDir);
+        return false;
+    }
+    tableNames = psStringCopy(metadataItem->data.V);
+
+    // Read time tables
+    namesPtr = tableNames;
+    while((tableName=getToken(&namesPtr, " ", &status)) != NULL) {
+
+        // Form path with table name, adding one to length for last '/' that may not occur in string in cong file
+        fullTableName = (char*)psAlloc(strlen(tableDir)+strlen(tableName)+1+1);
+
+        // Old strings may come back from psAlloc(), so set initial position to EOL
+        fullTableName[0]='\0';
+        strcat(fullTableName, tableDir);
+        strcat(fullTableName, "/");
+        strcat(fullTableName, tableName);
+
+        // Create and read table
+        if(i < numTables) {
+            table = psLookupTableAlloc(fullTableName, tablesFrom->data.F64[i], tablesTo->data.F64[i]);
+            table = psLookupTableRead(table);
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, i+1, numTables);
+        }
+
+        // Place tables into metadata slightly altered names as keys to create consistent naming conventions
+        foundTable = false;
+        for(j=0; j<numTables; j++) {
+            metadataNamesPtr = strstr(tableName, metadataTableNames[j]);
+            if(metadataNamesPtr != NULL) {
+                psMetadataAdd(timeMetadata, PS_LIST_TAIL, strcat(metadataTableNames[j], "Table"),
+                              PS_TYPE_PTR, PS_META_LOOKUPTABLE, NULL, table);
+                foundTable = true;
+            } else if(foundTable==false && j==numTables-1) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, j, numTables);
+            }
+        }
+
+        psFree(fullTableName);
+        psFree(tableName);
+        i++;
+    }
+
+    if(numTables != i) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, i, numTables);
+    }
+
+    psFree(tableDir);
+    psFree(tableNames);
+    psFree(tablesFrom);
+    psFree(tablesTo);
+
+    return true;
+}
+
+bool p_psTimeFinalize(void)
+{
+    if(timeMetadata != NULL) {
+        psFree(timeMetadata);
+        timeMetadata = NULL;
+    }
+
+    return true;
+}
+
+psTime* psTimeAlloc(psTimeType type)
+{
+    psTime *outTime = NULL;
+
+
+    // Error checks
+    if(type!=PS_TIME_TAI && type!=PS_TIME_UTC) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psTime_TYPE_UNKNOWN,
+                type);
+        return NULL;
+    }
+
+    outTime = (psTime*)psAlloc(sizeof(psTime));
+
+    outTime->sec = 0;
+    outTime->usec = 0;
+    outTime->type = type;
+
+    return outTime;
+}
+
+psTime* psTimeGetTime(psTimeType type)
+{
+    struct timeval now;
+    psTime *time = NULL;
+
+
+    // Allocate psTime struct
+    time = psTimeAlloc(type);
+
+    if (gettimeofday(&now, (struct timezone *)0) == -1) {
+        psError(PS_ERR_OS_CALL_FAILED, true,
+                PS_ERRORTEXT_psTime_GET_TOD_FAILED);
+        return NULL;
+    }
+
+    // Convert timeval time to psTime
+    time->sec = now.tv_sec;
+    time->usec = now.tv_usec;
+
+    // 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;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    if (time->type == type) { // time already right type.  That was easy!
+        return time;
+    }
+
+    delta = psTimeGetTAIDelta(time);
+
+    if (type == PS_TIME_UTC) {
+        time->sec = time->sec - delta;    // User wants UTC time. Subtract leapseconds.
+    } else if(type == PS_TIME_TAI) {
+        time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_UNKNOWN, 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 *tdtTime     = NULL;
+    psTime *taiTime     = NULL;
+    psTime *utcTime     = NULL;
+    psTime *ut1Time     = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // Calculate TAI or UTC time based on type of time user passes
+    if(time->type == PS_TIME_TAI) {
+        taiTime = psMemIncrRefCounter(time);
+        utcTime = psTimeAlloc(PS_TIME_UTC);
+        utcTime->sec = taiTime->sec - psTimeGetTAIDelta(time);
+        utcTime->usec = taiTime->usec;
+    } else if(time->type == PS_TIME_UTC) {
+        utcTime = psMemIncrRefCounter(time);
+        taiTime = psTimeAlloc(PS_TIME_TAI);
+        taiTime->sec = utcTime->sec + psTimeGetTAIDelta(time);
+        taiTime->usec = utcTime->usec;
+    }
+
+    // Convert Universal Time (UTC) to  UT1
+    ut1UtcDbl = psTimeGetUT1Delta(taiTime);
+    utcTime->type = PS_TIME_TAI; // Don't allow addition of leapseconds to ut1Time
+    ut1Time = psTimeMath(utcTime, ut1UtcDbl);
+    utcTime->type = PS_TIME_UTC;
+
+
+    // 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)
+    tdtTime = psTimeMath(taiTime, 32.184);
+
+    // 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(utcTime);
+    psFree(taiTime);
+
+    return lmstRad;
+}
+
+double psTimeGetUT1Delta(const psTime *time)
+{
+    psU32 nTables = 3;
+    psF64 mjd = 0.0;
+    psF64 result = 0.0;
+    psF64 dut2ut1 = 0.0;
+    psF64 t = 0.0;
+    psVector *dut = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+    psLookupStatusType status = PS_LOOKUP_SUCCESS;
+    char *metadataTableNames[3] = {"ser7Table", "eopcTable",  "finalsTable"};
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    if(time->type != PS_TIME_TAI) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_INCORRECT, time->type);
+        return 0.0;
+    }
+
+    // Attempt to find value through table lookup and interpolation
+    mjd = psTimeToMJD(time);
+    result = searchTables(mjd, 0, &status, metadataTableNames, nTables);
+
+    // Value could not be found through table lookup and interpolation
+    if(status == PS_LOOKUP_PAST_TOP) {
+
+        // Date too early for tables. Get default time delta value from metadata, and issue warning.
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES, mjd, "UT1-UTC");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.dut");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.dut");
+            return 0.0;
+        }
+        result = tableMetadataItem->data.F64;
+
+    } else if(status == PS_LOOKUP_PAST_BOTTOM) {
+        /* Date too late for tables. Issue warning and use following formulae for predicting
+           ahead of the most recent available table entry.
+             ut1-utc = [0] + [1]*(MJD - [2]) - (ut2-ut1)
+             [0, 1, 2] = @psLib.time.predict.dut
+             ut2-ut1 = 0.022 sin(2*pi*t) - 0.012 cos(2*pi*t) - 0.006 sin(4*pi*t) + 0.007 cos(4*pi*t)
+             t = 2000.0 + (MJD - 51544.03)/365.2422
+        */
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES, mjd, "UT1-UTC");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.dut");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.dut");
+            return 0.0;
+        }
+        dut = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(dut,0.0);
+
+        t = 2000.0 + (mjd - 51544.03)/365.2422;
+        dut2ut1 = 0.022*sin(TWOPI*t) - 0.012*cos(TWOPI*t) - 0.006*sin(4.0*M_PI*t) + 0.007*cos(4.0*M_PI*t);
+        result = dut->data.F64[0] + dut->data.F64[1]*(mjd - dut->data.F64[2]) - dut2ut1;
+
+    } else if(status != PS_LOOKUP_SUCCESS) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        return 0.0;
+    }
+
+    return result;
+}
+
+struct psSphere* psTimeGetPoleCoords(const psTime* time)
+{
+    psU32 nTables = 3;
+    psF64 x = 0.0;
+    psF64 y = 0.0;
+    psF64 mjd = 0.0;
+    psF64 a = 0.0;
+    psF64 c = 0.0;
+    psF64 mjdPred = 0.0;
+    struct psSphere* output = NULL;
+    psLookupStatusType xStatus = PS_LOOKUP_SUCCESS;
+    psLookupStatusType yStatus = PS_LOOKUP_SUCCESS;
+    psMetadataItem *tableMetadataItem = NULL;
+    char *metadataTableNames[3] = {"ser7Table", "eopcTable",  "finalsTable"};
+    psVector *xp = NULL;
+    psVector *yp = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    if(time->type != PS_TIME_TAI)
+    {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_INCORRECT, time->type);
+        return NULL;
+    }
+
+    // Attempt to find value through table lookup and interpolation
+    mjd = psTimeToMJD(time);
+    x = searchTables(mjd, 0, &xStatus, metadataTableNames, nTables);
+    y = searchTables(mjd, 0, &yStatus, metadataTableNames, nTables);
+
+    // Value could not be found through table lookup and interpolation
+    if(xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP)
+    {
+
+        // Date too earlier for tables. Get default polar coodinate values from metadata, and issue warning.
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES, mjd, "polar motion");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.xp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.xp");
+            return NULL;
+        }
+        x = tableMetadataItem->data.F64;
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.yp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.yp");
+            return NULL;
+        }
+        y = tableMetadataItem->data.F64;
+
+    } else if(xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM)
+    {
+
+        /* Date too late for tables. Issue warning and use following formulae for predicting
+           ahead of the most recent available table entry.
+              x = [0] + [1]*cos a + [2]*sin a + [3]*cos c + [4]*sin c
+              [0], [1], [2], [3] = @psLib.time.predict.xp
+              y = [0] + [1]*cos a + [2]*sin a + [3]*cos c + [4]*sin c
+              [0], [1], [2], [3] = @psLib.time.predict.yp
+              a = 2*pi*(mjd - pslib.time.predict.mjd)/365.25
+              c = 2*pi*(mjd - pslib.time.predict.mjd)/435.0
+        */
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES, mjd, "polar motion");
+
+
+        // Get predicted MJD
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.mjd");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                    "psLib.time.predict.mjd");
+            return NULL;
+        }
+        mjdPred = tableMetadataItem->data.F64;
+
+        // Get xp
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.xp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.xp");
+            return NULL;
+        }
+        xp = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(xp,NULL);
+
+        // Get yp
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.yp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.yp");
+            return NULL;
+        }
+        yp = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(yp,NULL);
+
+        // Calculate "a" and "c" constants
+        a = TWOPI*(mjd - mjdPred)/365.25;
+        c = TWOPI*(mjd - mjdPred)/435.0;
+
+        // Calculate x and y polar coordinates
+        x = xp->data.F64[0] +
+            xp->data.F64[1]*cos(a) +
+            xp->data.F64[2]*sin(a) +
+            xp->data.F64[3]*cos(c) +
+            xp->data.F64[4]*sin(c);
+
+        y = yp->data.F64[0] +
+            yp->data.F64[1]*cos(a) +
+            yp->data.F64[2]*sin(a) +
+            yp->data.F64[3]*cos(c) +
+            yp->data.F64[4]*sin(c);
+
+    } else if(xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS)
+    {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        return NULL;
+    }
+
+    // Create output sphere and convert arcsec to radians (i.e. x/60/60*M_PI/180)
+    output = psAlloc(sizeof(psSphere));
+    output->r = x * M_PI / 648000.0;
+    output->d = y * M_PI / 648000.0;
+
+    return output;
+}
+
+double psTimeGetTAIDelta(const psTime *time)
+{
+    psU64 i = 0;
+    psF64 jd = 0.0;
+    psF64 mjd = 0.0;
+    psF64 out = 0.0;
+    psF64 const1 = 0.0;
+    psF64 const2 = 0.0;
+    psF64 const3 = 0.0;
+    psLookupTable* table = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+    psVector *stats = NULL;
+    psVector *results = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // Check time metadata
+    if(timeMetadata == NULL) {
+        if(!p_psTimeInit(TIME_CONFIG_FILE)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_FILE_NOT_FOUND, "psTime.config");
+            return 0.0;
+        }
+    }
+
+    // Get table from metadata
+    tableMetadataItem = psMetadataLookup(timeMetadata, "taiTable");
+    if(tableMetadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "taiTable");
+        return 0.0;
+    }
+    table = (psLookupTable*)tableMetadataItem->data.V;
+    PS_PTR_CHECK_NULL(table,0);
+
+    // Determine Julian and modified Julian dates used in table lookup and time delta calculation
+    jd = psTimeToJD(time);
+    mjd = psTimeToMJD(time);
+
+    stats = psVectorAlloc(table->numCols, PS_TYPE_U32);
+    results = psLookupTableInterpolateAll(table, jd, stats);
+
+    // Check for successful interpolation
+    for(i=0; i<stats->n; i++) {
+        if(stats->data.U32[i] == PS_LOOKUP_ERROR) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        }
+    }
+
+    const1 = results->data.F64[0];
+    const2 = results->data.F64[1];
+    const3 = results->data.F64[2];
+    out = const1 + (mjd - const2) * const3;
+
+    psFree(stats);
+    psFree(results);
+
+    return out;
+}
+
+
+psS64 psTimeLeapseconds(const psTime *time1, const psTime *time2)
+{
+    psS64 diff = 0;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time1,0);
+    PS_PTR_CHECK_NULL(time2,0);
+    PS_INT_CHECK_RANGE(time1->usec,0,1e6-1,0);
+    PS_INT_CHECK_RANGE(time2->usec,0,1e6-1,0);
+    diff = abs((psS64)psTimeGetTAIDelta((psTime*)time1)-(psS64)psTimeGetTAIDelta((psTime*)time2));
+
+    return diff;
+}
+
+double psTimeToJD(const psTime *time)
+{
+    double jd = 0.0;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // 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;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // 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)
+{
+    psS32 ms = 0;
+    char *timeString = NULL;
+    char *tempString = NULL;
+    struct tm *tmTime = NULL;
+    time_t sec;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,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(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED);
+    }
+
+    if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
+        psError(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED);
+    }
+    psFree(tempString);
+
+    return timeString;
+}
+
+struct timeval psTimeToTimeval(const psTime *time)
+{
+    struct timeval timevalTime;
+
+    timevalTime.tv_sec = 0;
+    timevalTime.tv_usec = 0;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,timevalTime);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,timevalTime);
+
+    timevalTime.tv_sec = time->sec;
+    timevalTime.tv_usec = time->usec;
+
+    return timevalTime;
+}
+
+struct tm* psTimeToTM(const psTime *time)
+{
+    psS64 cent = 0;
+    psS64 year = 0;
+    psS64 month = 0;
+    psS64 day = 0;
+    psS64 hour = 0;
+    psS64 minute = 0;
+    psS64 seconds = 0;
+    psS64 temp = 0;
+    struct tm* tmTime = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,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));
+
+    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
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Julian date conversion courtesy of Eugene Magnier
+    days = time - 2440587.5;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (psS64)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (psS64)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromMJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Modified Julian date conversion courtesy of Eugene Magnier
+    days = time - 40587.0;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (psS64)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (psS64)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromISOTime(const char *time)
+{
+    psS32 millisecond;
+    struct tm tmTime;
+    psTime *outTime = NULL;
+
+    // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
+    if (sscanf(time, "%d-%d-%dT%d:%d:%d.%d", &tmTime.tm_year, &tmTime.tm_mon, &tmTime.tm_mday,
+               &tmTime.tm_hour, &tmTime.tm_min, &tmTime.tm_sec,&millisecond) < 7) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_ISOTIME_MALFORMED, time);
+        return NULL;
+    }
+
+    PS_INT_CHECK_NON_NEGATIVE(tmTime.tm_year, outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_mon,1,12,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_mday,1,31,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_hour,0,23,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_min,0,59,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_sec,0,59,outTime);
+    PS_INT_CHECK_RANGE(millisecond,0,999,outTime);
+
+    tmTime.tm_year -= 1900;
+    tmTime.tm_mon--;
+    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;
+
+
+    // Error check
+    PS_PTR_CHECK_NULL(time,NULL);
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Convert to psTime
+    outTime->sec = time->tv_sec;
+    outTime->usec = time->tv_usec;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromTM(const struct tm* time)
+{
+    psS64 year;
+    psS64 month;
+    psS64 day;
+    psS64 hour;
+    psS64 minute;
+    psS64 seconds;
+    psS64 temp;
+    psTime *outTime = NULL;
+
+
+    // Error check
+    PS_PTR_CHECK_NULL(time,NULL);
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // 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;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeMath(const psTime *time, psF64 delta)
+{
+    psF64 sec = 0.0;
+    psTime *outTime = NULL;
+    psTime *tempTime = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time->type == PS_TIME_UTC) {
+        tempTime = psTimeAlloc(PS_TIME_UTC);
+        tempTime->sec = time->sec;
+        tempTime->usec = time->usec;
+        tempTime = psTimeConvert(tempTime, PS_TIME_TAI);
+    } else {
+        tempTime = psMemIncrRefCounter((psTime*)time);
+    }
+
+    // Create output time
+    outTime = psTimeAlloc(PS_TIME_TAI);
+    sec = delta + (psF64)tempTime->sec + (psF64)tempTime->usec/1e6;
+    outTime->sec = sec;
+    outTime->usec = (sec - outTime->sec)*1e6;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    // Convert result to same time type as input
+    if(time->type == PS_TIME_UTC) {
+        outTime = psTimeConvert(outTime, PS_TIME_UTC);
+    }
+
+    psFree(tempTime);
+
+    return outTime;
+}
+
+psF64 psTimeDelta(const psTime *time1, const psTime *time2)
+{
+    psF64 out = 0.0;
+    psF64 uSec1 = 0.0;
+    psF64 uSec2 = 0.0;
+    psTime *tempTime1 = NULL;
+    psTime *tempTime2 = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time1,0.0);
+    PS_INT_CHECK_RANGE(time1->usec,0,1e6-1,0.0);
+    PS_PTR_CHECK_NULL(time2,0.0);
+    PS_INT_CHECK_RANGE(time2->usec,0,1e6-1,0.0);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time1->type == PS_TIME_UTC) {
+        tempTime1 = psTimeAlloc(PS_TIME_UTC);
+        tempTime1->sec = time1->sec;
+        tempTime1->usec = time1->usec;
+        tempTime1 = psTimeConvert(tempTime1, PS_TIME_TAI);
+    } else {
+        tempTime1 = psMemIncrRefCounter((psTime*)time1);
+    }
+    if(time2->type == PS_TIME_UTC) {
+        tempTime2 = psTimeAlloc(PS_TIME_UTC);
+        tempTime2->sec = time2->sec;
+        tempTime2->usec = time2->usec;
+        tempTime2 = psTimeConvert(tempTime2, PS_TIME_TAI);
+    } else {
+        tempTime2 = psMemIncrRefCounter((psTime*)time2);
+    }
+
+    uSec1 = tempTime1->sec >= 0 ? 1.0 : -1.0;
+    uSec1 = uSec1*tempTime1->usec/1e6;
+    uSec2 = tempTime2->sec >= 0 ? 1.0 : -1.0;
+    uSec2 = uSec2*tempTime2->usec/1e6;
+    out = (tempTime1->sec-tempTime2->sec) + (uSec1-uSec2);
+
+    psFree(tempTime1);
+    psFree(tempTime2);
+
+    return out;
+}
+
Index: /branches/rel4/psLib/src/astro/psTime.h
===================================================================
--- /branches/rel4/psLib/src/astro/psTime.h	(revision 3057)
+++ /branches/rel4/psLib/src/astro/psTime.h	(revision 3057)
@@ -0,0 +1,288 @@
+/** @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.  They use the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-16 18:52:51 $
+ *
+ *  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;
+
+
+/** Initialize time data.
+ *
+ * Reads config and data files associated with various time conversions.
+ *
+ * @return  bool: True for success, false for failure.
+ */
+psBool p_psTimeInit(const char *fileName);
+
+/** Free memory persistant time data.
+ *
+ * Frees time data to be held in memory until the end of successful program execution.
+ *
+ * @return  void: void.
+ */
+psBool p_psTimeFinalize(void);
+
+/** Allocate time struct.
+ *
+ * Allocates an empty time struct. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in the argument.
+ * The seconds and microseconds members of the struct are set to zero.
+ *
+ * @return  psTime*: Struct with empty time.
+ */
+psTime* psTimeAlloc(
+    psTimeType type                     ///< Type of time to create (UTC or TAI).
+);
+
+/** 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  psS64: leapseconds added between given times
+ */
+psS64 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.
+);
+
+/** Adds delta to time. Result is in TAI time.
+ *
+ *  Adds delta to time. Input time is converted to TAI format if necessary.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeMath(
+    const psTime *time,                 ///< Time.
+    psF64 delta                         ///< Time delta.
+);
+
+/** Determine difference between two times. Result is in TAI time.
+ *
+ *  Determine difference between two times. Input times are converted to TAI format if necessary.
+ *
+ *  @return psF64: Time difference.
+ */
+psF64 psTimeDelta(
+    const psTime *time1,                ///< First time.
+    const psTime *time2                 ///< Second time.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/Makefile
===================================================================
--- /branches/rel4/psLib/src/astronomy/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/Makefile	(revision 3057)
@@ -0,0 +1,65 @@
+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 -I../fileUtils \
+    -DTIME_CONFIG_FILE="\"$(TIME_CONFIG_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 | sed 's|[A-Za-z0-9\/\.]*libxml[A-Za-z0-9\/\.]*||g' > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel4/psLib/src/astronomy/psAstrometry.c
===================================================================
--- /branches/rel4/psLib/src/astronomy/psAstrometry.c	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psAstrometry.c	(revision 3057)
@@ -0,0 +1,909 @@
+/** @file  psAstrometry.c
+ *
+ *  @brief This file defines the basic types for astronomical coordinate
+ *  transformation
+ *
+ *  @ingroup AstroImage
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  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 "psError.h"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+#include "psTrace.h"
+#include "psLogMsg.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 psS32 checkValidImageCoords(double x,
+                                   double y,
+                                   psImage* tmpImage)
+{
+    PS_IMAGE_CHECK_NULL(tmpImage, 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 psS32 isProjectionLinear(psPlaneTransform *transform)
+{
+    PS_PTR_CHECK_NULL(transform, 0);
+    PS_PTR_CHECK_NULL(transform->x, 0);
+    PS_PTR_CHECK_NULL(transform->y, 0);
+
+    int i;
+
+    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)
+{
+    PS_PTR_CHECK_NULL(transform, 0);
+    PS_PTR_CHECK_NULL(transform->x, 0);
+    PS_PTR_CHECK_NULL(transform->y, 0);
+
+    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];
+
+    // XXX: Use the constructor here.
+    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);
+        psFree(cell->toSky);
+    }
+}
+
+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((psPtr)obs->name);
+    }
+}
+
+static void exposureFree(psExposure* exp)
+{
+    if (exp != NULL) {
+        psFree((psPtr)exp->time);
+        psFree((psPtr)exp->observatory);
+        psFree((psPtr)exp->cameraName);
+        psFree((psPtr)exp->telescopeName);
+    }
+}
+
+static void fixedPatternFree(psFixedPattern* fp)
+{
+    if (fp != NULL) {
+        for (psS32 i = 0; i < fp->p_ps_xRows; i++) {
+            psFree(fp->x[i]);
+        }
+
+        for (psS32 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;
+    psS32 i;
+    psS32 j;
+
+    PS_IMAGE_CHECK_NULL(x, NULL);
+    PS_IMAGE_CHECK_NULL(y, NULL);
+    PS_IMAGE_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_IMAGE_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+
+    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_PTR_CHECK_NULL(observatory, NULL);
+
+    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((psPtr)time);
+    exp->observatory = psMemIncrRefCounter((psPtr)observatory);
+
+    // XXX: how is this 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(psS32 nChips,
+                  const psExposure* exp)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nChips, NULL);
+
+    psFPA* newFPA = psAlloc(sizeof(psFPA));
+
+    // create array of NULL chips of the size nChips
+    newFPA->chips = psArrayAlloc(nChips);
+    psPtr* chips = newFPA->chips->data;
+    for (psS32 i=0;i<nChips;i++) {
+        chips[i] = NULL;
+    }
+    newFPA->chips->n = 0; // per requirement
+
+    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(psS32 nCells,
+                    psFPA *parentFPA)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nCells, NULL);
+
+    psChip* chip = psAlloc(sizeof(psChip));
+
+    // create array of NULL psCells
+    int n = (nCells > 0) ? nCells : 1;
+    chip->cells = psArrayAlloc(n);
+    psPtr* cells = chip->cells->data;
+    for (psS32 i=0;i<n;i++) {
+        cells[i] = NULL;
+    }
+    chip->cells->n = 0; // per requirement
+
+    *(int*)&chip->row0 = 0;
+    *(int*)&chip->col0 = 0;
+
+    chip->metadata = NULL;
+
+    chip->toFPA = NULL;
+    chip->fromFPA = NULL;
+
+    chip->parent = parentFPA;
+
+    p_psMemSetDeallocator(chip,(psFreeFcn)chipFree);
+
+    return chip;
+
+}
+
+/*
+ * psCell constructor
+ */
+psCell* psCellAlloc(psS32 nReadouts,
+                    psChip* parentChip)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nReadouts, NULL);
+
+    psCell* cell = psAlloc(sizeof(psCell));
+
+    // create array of NULL psReadouts
+    int n = (nReadouts > 0) ? nReadouts : 1;
+    cell->readouts = psArrayAlloc(n);
+    psPtr* readouts = cell->readouts->data;
+    for (psS32 i=0;i<n;i++) {
+        readouts[i] = NULL;
+    }
+    cell->readouts->n = 0; // per requirement
+
+    *(int*)&cell->row0 = 0;
+    *(int*)&cell->col0 = 0;
+
+    cell->metadata = NULL;
+
+    cell->toChip = NULL;
+    cell->fromChip = NULL;
+    cell->toFPA = NULL;
+    cell->toTP = NULL;
+    cell->toSky = NULL;
+
+    cell->parent = parentChip;
+
+    p_psMemSetDeallocator(cell,(psFreeFcn)cellFree);
+
+    return cell;
+
+
+}
+
+psReadout* psReadoutAlloc()
+{
+    psReadout* readout = psAlloc(sizeof(psReadout));
+
+    *(psU32*)&readout->colBins = 1;
+    *(psU32*)&readout->rowBins = 1;
+    *(psU32*)&readout->rowParity = 0;
+    *(psU32*)&readout->colParity = 0;
+    *(psS32*)&readout->col0 = 0;
+    *(psS32*)&readout->row0 = 0;
+
+    readout->image = NULL;
+    readout->mask = NULL;
+    readout->objects = NULL;
+    readout->metadata = NULL;
+
+    p_psMemSetDeallocator(readout,(psFreeFcn)readoutFree);
+
+    return readout;
+}
+
+psGrommit* psGrommitAlloc(const psExposure* exp)
+{
+    PS_PTR_CHECK_NULL(exp, NULL);
+
+    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_PTR_CHECK_NULL(fpaCoord, NULL);
+    PS_PTR_CHECK_NULL(FPA, NULL);
+
+    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_PTR_CHECK_NULL(fpaCoord, NULL);
+    PS_PTR_CHECK_NULL(FPA, NULL);
+    PS_PTR_CHECK_NULL(FPA->chips, NULL);
+
+    psArray* chips = FPA->chips;
+    psS32 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 (psS32 i = 0; i < nChips; i++) {
+        psChip* tmpChip = chips->data[i];
+        PS_PTR_CHECK_NULL(tmpChip, NULL);
+        PS_PTR_CHECK_NULL(tmpChip->fromFPA, NULL);
+
+        psPlaneTransformApply(&chipCoord, tmpChip->fromFPA, fpaCoord);
+
+        tmpCell = psCellInChip(&chipCoord, tmpChip);
+        if (tmpCell != NULL) {
+            return(tmpChip);
+        }
+    }
+
+    // XXX: Print warning here?
+    return (NULL);
+}
+
+psCell* psCellInChip(const psPlane* chipCoord,
+                     const psChip* chip)
+{
+    PS_PTR_CHECK_NULL(chipCoord, NULL);
+    PS_PTR_CHECK_NULL(chip, NULL);
+
+    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 (psS32 i = 0; i < cells->n; i++) {
+        psCell* tmpCell = (psCell* ) cells->data[i];
+        PS_PTR_CHECK_NULL(tmpCell, NULL);
+        PS_PTR_CHECK_NULL(tmpCell->fromChip, NULL);
+        psArray* readouts = tmpCell->readouts;
+
+        if (readouts != NULL) {
+            for (psS32 j = 0; j < readouts->n; j++) {
+                psReadout* tmpReadout = readouts->data[j];
+                PS_READOUT_CHECK_NULL(tmpReadout, NULL);
+
+                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_PTR_CHECK_NULL(inCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+
+    return (psPlaneTransformApply(outCoord, cell->toChip, inCoord));
+}
+
+psPlane* psCoordChipToFPA(psPlane* outCoord,
+                          const psPlane* inCoord,
+                          const psChip* chip)
+{
+    PS_PTR_CHECK_NULL(inCoord, NULL);
+    PS_PTR_CHECK_NULL(chip, NULL);
+
+    return (psPlaneTransformApply(outCoord, chip->toFPA, inCoord));
+}
+
+psPlane* psCoordFPAToTP(psPlane* outCoord,
+                        const psPlane* inCoord,
+                        double color,
+                        double magnitude,
+                        const psFPA* fpa)
+{
+    PS_PTR_CHECK_NULL(inCoord, NULL);
+    PS_PTR_CHECK_NULL(fpa, NULL);
+
+    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_PTR_CHECK_NULL(tpCoord, NULL);
+    PS_PTR_CHECK_NULL(grommit, NULL);
+
+    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_PTR_CHECK_NULL(cellCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+
+    return (psPlaneTransformApply(fpaCoord, cell->toFPA, cellCoord));
+}
+
+psSphere* psCoordCellToSky(psSphere* skyCoord,
+                           const psPlane* cellCoord,
+                           double color,
+                           double magnitude,
+                           const psCell* cell)
+{
+    PS_PTR_CHECK_NULL(cellCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+    PS_PTR_CHECK_NULL(cell->toFPA, NULL);
+    PS_PTR_CHECK_NULL(cell->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent->toTangentPlane, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent->exposure, NULL);
+
+    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_PTR_CHECK_NULL(cellCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+    PS_PTR_CHECK_NULL(cell->toSky, NULL);
+    PS_PTR_CHECK_NULL(cell->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent->projection, NULL);
+    if (cell->toSky) {
+        // XXX: Should we use toTP or toSky?
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: psCoordCellToSkyQuick(): The cell->toSky transform is ignored.  The cell->toTP transform is being used.");
+    }
+
+    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(NULL, 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_PTR_CHECK_NULL(in, NULL);
+    PS_PTR_CHECK_NULL(grommit, NULL);
+
+    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_PTR_CHECK_NULL(tpCoord, NULL);
+    PS_PTR_CHECK_NULL(fpa, NULL);
+    PS_PTR_CHECK_NULL(fpa->fromTangentPlane, NULL);
+
+    return (psPlaneDistortApply(fpaCoord, fpa->fromTangentPlane,
+                                tpCoord, color, magnitude));
+}
+
+psPlane* psCoordFPAToChip(psPlane* chipCoord,
+                          const psPlane* fpaCoord,
+                          const psChip* chip)
+{
+    PS_PTR_CHECK_NULL(fpaCoord, NULL);
+    PS_PTR_CHECK_NULL(chip, NULL);
+    PS_PTR_CHECK_NULL(chip->fromFPA, NULL);
+
+    chipCoord = psPlaneTransformApply(chipCoord, chip->fromFPA, fpaCoord);
+    return(chipCoord);
+}
+
+psPlane* psCoordChipToCell(psPlane* cellCoord,
+                           const psPlane* chipCoord,
+                           const psCell* cell)
+{
+    PS_PTR_CHECK_NULL(chipCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+    PS_PTR_CHECK_NULL(cell->fromChip, NULL);
+
+    cellCoord = psPlaneTransformApply(cellCoord, cell->fromChip, chipCoord);
+    return(cellCoord);
+}
+
+psPlane* psCoordSkyToCell(psPlane* cellCoord,
+                          const psSphere* skyCoord,
+                          double color,
+                          double magnitude,
+                          const psCell* cell)
+{
+    PS_PTR_CHECK_NULL(skyCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+    PS_PTR_CHECK_NULL(cell->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent->grommit, NULL);
+
+    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_PTR_CHECK_NULL(skyCoord, NULL);
+    PS_PTR_CHECK_NULL(cell, NULL);
+    PS_PTR_CHECK_NULL(cell->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent, NULL);
+    PS_PTR_CHECK_NULL(cell->parent->parent->projection, NULL);
+    PS_PTR_CHECK_NULL(cell->toTP, NULL);
+    if (cell->toSky) {
+        // XXX: Should we use toTP or toSky?
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: psCoordSkyToCellQuick(): The cell->toSky transform is ignored.  The cell->toTP transform is being used.");
+    }
+
+    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)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM,
+                "cell to tangent plane");
+    }
+
+    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/rel4/psLib/src/astronomy/psAstrometry.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psAstrometry.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psAstrometry.h	(revision 3057)
@@ -0,0 +1,536 @@
+/** @file  psAstrometry.h
+*
+*  @brief This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup AstroImage
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-30 20:18:36 $
+*
+*  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
+{
+    psS32 nX;                            ///< Number of elements in x direction
+    psS32 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.
+    psS32 p_ps_xRows;                    ///< Number of rows in the x member
+    psS32 p_ps_xCols;                    ///< Number of cols in the x member
+    psS32 p_ps_yRows;                    ///< Number of rows in the y member
+    psS32 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 psS32 col0;                  ///< Offset from the left of chip.
+    const psS32 row0;                  ///< Offset from the bottom of chip.
+
+    const int colParity;               ///< Column Readout Direction
+    const int rowParity;               ///< Row Readout Direction
+
+    const psU32 colBins;               ///< Amount of binning in x-dimension
+    const psU32 rowBins;               ///< Amount of binning in y-dimension
+
+    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
+{
+    const psS32 col0;                  ///< Offset from the left of chip
+    const psS32 row0;                  ///< Offset from the bottom of chip
+
+    psArray* readouts;                 ///< readouts from the cell
+
+    psMetadata* metadata;              ///< cell-level metadata
+
+    psPlaneTransform* toChip;          ///< transformations from cell to chip coordinates
+    psPlaneTransform* fromChip;        ///< transformations from cell to chip coordinates
+    psPlaneTransform* toFPA;           ///< transformations from cell to FPA coordinates
+    psPlaneTransform* toTP;            ///< transformations from cell to FPA coordinates
+    psPlaneTransform* toSky;           ///< 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
+{
+    const psS32 col0;                  ///< Offset from the left of FPA
+    const psS32 row0;                  ///< Offset from the bottom of FPA
+
+    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(
+    psS32 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(
+    psS32 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(
+    psS32 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 with all internal pointers set to NULL
+ */
+psReadout* psReadoutAlloc();
+
+/** 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/rel4/psLib/src/astronomy/psAstronomyErrors.dat
===================================================================
--- /branches/rel4/psLib/src/astronomy/psAstronomyErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psAstronomyErrors.dat	(revision 3057)
@@ -0,0 +1,63 @@
+#
+#  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
+####################################################################
+psTime_FILE_NOT_FOUND                  Failed to open file %s.
+psTime_FILE_TOO_MANY_ROWS              Too many rows found in file %s. Max number of rows allowed is %d.
+psTime_TIME_POSTDATES_TABLE            Specified psTime postdates (%g) the table of %s information.
+psTime_TIME_PREDATES_TABLE             Specified psTime predates (%g) the table of %s information.
+psTime_TIME_POSTDATES_TABLES           Specified psTime postdates (%g) all tables of %s information.
+psTime_TIME_PREDATES_TABLES            Specified psTime predates (%g) all tables of %s information.
+psTime_TABLE_DUPLICATE_ROWS            The %s table was found to have two rows of the same time value.
+psTime_TYPE_UNKNOWN                    Specified type, %d, is not supported.
+psTime_TYPE_INCORRECT                  Specified type, %d, is incorrect.
+psTime_TYPE_MISMATCH                   Specified psTime parameters must have same type.
+psTime_GET_TOD_FAILED                  Failed to determine the current time from gettimeofday function.
+psTime_CONVERT_TIME_TO_STRING_FAILED   Failed to convert a time via strftime function.
+psTime_APPEND_MSEC_FAILED              Failed to append millisecond to time string with snprintf function.
+psTime_USEC_INVALID                    The psTime usec attribute value, %u, is invalid.  Must be less than 1e6.
+psTime_ISOTIME_MALFORMED               Specified ISO Time string, '%s', is malformed.  Must be in 'YYYY-MM-DDThh:mm:ss.sss' format.
+psTime_INTERPOLATION_FAILED            Failed time table interpolation.
+psTime_INTERPOLATION_FAILED_NAME       Failed time table interpolation for '%s'.
+psTime_LOOKUP_METADATA_FAILED          Failed find '%s' in time metadata.
+psTime_BAD_TABLE_COUNT                 Incorrect number of table files entered. Found: %d. Expected: %d.
+psTime_BAD_VECTOR                      Incorrect vector size. Size: %d, Expected %d.
+#
+psCoord_PROJECTION_TYPE_UNDEFINED      The projection type, %s, is undefined.
+psCoord_PROJECTION_TYPE_UNKNOWN        The projection type, %d, is unknown.
+psCoord_UNITS_UNKNOWN                  Specified units, 0x%x, is not supported.
+psCoord_OFFSET_MODE_UNKNOWN            Specified offset mode, 0x%x, is not supported.
+#
+psAstrometry_NONLINEAR_TRANSFORM       The %s transfrom is not linear.  Only linear transforms are supported.
+#
+psMetadata_METATYPE_INVALID            Specified psMetadataType, %d, is not supported.
+psMetadata_METATYPE_MISMATCH           Specified psMetadataType, %d, is incorrect. Expected %d.
+psMetadata_ADD_LIST_FAILED             Failed to add metadata item, %s, to items list.
+psMetadata_ADD_TABLE_FAILED            Failed to add metadata item, %s, to items table.
+psMetadata_REMOVE_LIST_FAILED          Failed to remove metadata item, %s, from metadata list.
+psMetadata_REMOVE_LIST_INDEX_FAILED    Failed to remove metadata item, at index %d, from metadata list.
+psMetadata_REMOVE_TABLE_FAILED         Failed to remove metadata item, %s, from metadata table.
+psMetadata_ADD_COLLECTION_FAILED       Failed to add metadata item, %s, to metadata collection list.
+psMetadata_ADD_FAILED                  Failed to add metadata item to metadata collection list.
+psMetadata_FIND_FAILED                 Could not find metadata item, %s.
+psMetadata_FIND_INDEX_FAILED           Could not find metadata item at index %d.
+#
+psMetadataIO_TYPE_INVALID              Specified type, %d, is not supported.
+psMetadataIO_EXTNUM_NOTPOSITIVE        Specified extension number, %d, is invalid.  Value must be positive if no extension name is given.
+psMetadataIO_FITS_METATYPE_INVALID     Specified FITS metadata type, %c, is not supported.
+psMetadataIO_ADD_FAILED                Failed to add metadata item, %s.
+psMetadataIO_FILE_OPEN_FAILED          Failed to open file '%s'. Check if it exists and it has the proper permissions.
+psMetadataIO_FILE_MULTIPLE_CHAR        More than one '%c' character not allowed.  Found on line %u of %s.
+psMetadataIO_FILE_ELEMENT_NULL         Failed to read a metadata %s on line %u of %s.
+psMetadataIO_FILE_TYPE_INVALID         Metadata type '%s', found on line %u of %s, is not invalid.
+psMetadataIO_OVERWRITE_ITEM            Duplicate Metadata item, %s, found on line %u of %s.  Overwrite not allowed.
+psMetadataIO_PARSE_FAILED              Failed to parse the value '%s' of metadata item %s, type %s, on line %u of %s.
+psMetadataIO_NO_NAME                   Failed to find key 'name' in table on line %u of %s.
+psMetadataIO_TYPE_INVALID_LINE_FILE    Specified type, %s, is not supported on line %u of %s.
+psMetadataIO_TAG_MISMATCH              Start tag, %s and end tag, %s do not agree.
+psMetadataIO_TAG_UNKNOWN               Invalid end tag name, %s.
+
Index: /branches/rel4/psLib/src/astronomy/psAstronomyErrors.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psAstronomyErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psAstronomyErrors.h	(revision 3057)
@@ -0,0 +1,84 @@
+/** @file  psAstronomyErrors.h
+ *
+ *  @brief Contains the error text for the astronomy functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-07 19:09:18 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ASTRONOMY_ERRORS_H
+#define PS_ASTRONOMY_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_psTime_FILE_NOT_FOUND "Failed to open file %s."
+#define PS_ERRORTEXT_psTime_FILE_TOO_MANY_ROWS "Too many rows found in file %s. Max number of rows allowed is %d."
+#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLE "Specified psTime postdates (%g) the table of %s information."
+#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLE "Specified psTime predates (%g) the table of %s information."
+#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES "Specified psTime postdates (%g) all tables of %s information."
+#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES "Specified psTime predates (%g) all tables of %s information."
+#define PS_ERRORTEXT_psTime_TABLE_DUPLICATE_ROWS "The %s table was found to have two rows of the same time value."
+#define PS_ERRORTEXT_psTime_TYPE_UNKNOWN "Specified type, %d, is not supported."
+#define PS_ERRORTEXT_psTime_TYPE_INCORRECT "Specified type, %d, is incorrect."
+#define PS_ERRORTEXT_psTime_TYPE_MISMATCH "Specified psTime parameters must have same type."
+#define PS_ERRORTEXT_psTime_GET_TOD_FAILED "Failed to determine the current time from gettimeofday function."
+#define PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED "Failed to convert a time via strftime function."
+#define PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED "Failed to append millisecond to time string with snprintf function."
+#define PS_ERRORTEXT_psTime_USEC_INVALID "The psTime usec attribute value, %u, is invalid.  Must be less than 1e6."
+#define PS_ERRORTEXT_psTime_ISOTIME_MALFORMED "Specified ISO Time string, '%s', is malformed.  Must be in 'YYYY-MM-DDThh:mm:ss.sss' format."
+#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED "Failed time table interpolation."
+#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME "Failed time table interpolation for '%s'."
+#define PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED "Failed find '%s' in time metadata."
+#define PS_ERRORTEXT_psTime_BAD_TABLE_COUNT "Incorrect number of table files entered. Found: %d. Expected: %d."
+#define PS_ERRORTEXT_psTime_BAD_VECTOR "Incorrect vector size. Size: %d, Expected %d."
+#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED "The projection type, %s, is undefined."
+#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN "The projection type, %d, is unknown."
+#define PS_ERRORTEXT_psCoord_UNITS_UNKNOWN "Specified units, 0x%x, is not supported."
+#define PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN "Specified offset mode, 0x%x, is not supported."
+#define PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM "The %s transfrom is not linear.  Only linear transforms are supported."
+#define PS_ERRORTEXT_psMetadata_METATYPE_INVALID "Specified psMetadataType, %d, is not supported."
+#define PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH "Specified psMetadataType, %d, is incorrect. Expected %d."
+#define PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED "Failed to add metadata item, %s, to items list."
+#define PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED "Failed to add metadata item, %s, to items table."
+#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED "Failed to remove metadata item, %s, from metadata list."
+#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED "Failed to remove metadata item, at index %d, from metadata list."
+#define PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED "Failed to remove metadata item, %s, from metadata table."
+#define PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED "Failed to add metadata item, %s, to metadata collection list."
+#define PS_ERRORTEXT_psMetadata_ADD_FAILED "Failed to add metadata item to metadata collection list."
+#define PS_ERRORTEXT_psMetadata_FIND_FAILED "Could not find metadata item, %s."
+#define PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED "Could not find metadata item at index %d."
+#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID "Specified type, %d, is not supported."
+#define PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE "Specified extension number, %d, is invalid.  Value must be positive if no extension name is given."
+#define PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
+#define PS_ERRORTEXT_psMetadataIO_ADD_FAILED "Failed to add metadata item, %s."
+#define PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED "Failed to open file '%s'. Check if it exists and it has the proper permissions."
+#define PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR "More than one '%c' character not allowed.  Found on line %u of %s."
+#define PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL "Failed to read a metadata %s on line %u of %s."
+#define PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID "Metadata type '%s', found on line %u of %s, is not invalid."
+#define PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM "Duplicate Metadata item, %s, found on line %u of %s.  Overwrite not allowed."
+#define PS_ERRORTEXT_psMetadataIO_PARSE_FAILED "Failed to parse the value '%s' of metadata item %s, type %s, on line %u of %s."
+#define PS_ERRORTEXT_psMetadataIO_NO_NAME "Failed to find key 'name' in table on line %u of %s."
+#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE "Specified type, %s, is not supported on line %u of %s."
+#define PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH "Start tag, %s and end tag, %s do not agree."
+#define PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN "Invalid end tag name, %s."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/psCoord.c
===================================================================
--- /branches/rel4/psLib/src/astronomy/psCoord.c	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psCoord.c	(revision 3057)
@@ -0,0 +1,682 @@
+/** @file  psCoord.c
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.46 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-14 23:27:55 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psType.h"
+#include "psCoord.h"
+#include "psMemory.h"
+#include "psTime.h"
+#include "psConstants.h"
+#include "psError.h"
+#include "psLogMsg.h"
+#include "psAstronomyErrors.h"
+#include <math.h>
+#include <float.h>
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+// None
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+static void planeTransformFree(psPlaneTransform *pt)
+{
+    psFree(pt->x);
+    psFree(pt->y);
+}
+
+psPlaneTransform* psPlaneTransformAlloc(psS32 n1, psS32 n2)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n1, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n2, NULL);
+
+    psPlaneTransform *pt = psAlloc(sizeof(psPlaneTransform));
+    pt->x = psDPolynomial2DAlloc(n1, n2, PS_POLYNOMIAL_ORD);
+    pt->y = psDPolynomial2DAlloc(n1, n2, PS_POLYNOMIAL_ORD);
+
+    p_psMemSetDeallocator(pt, (psFreeFcn) planeTransformFree);
+    return(pt);
+}
+
+psPlane* psPlaneTransformApply(psPlane* out,
+                               const psPlaneTransform* transform,
+                               const psPlane* coords)
+{
+    PS_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(transform->x, NULL);
+    PS_PTR_CHECK_NULL(transform->y, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial2DEval(
+                 transform->x,
+                 coords->x,
+                 coords->y
+             );
+    out->y = psDPolynomial2DEval(
+                 transform->y,
+                 coords->x,
+                 coords->y
+             );
+    return (out);
+}
+
+static void planeDistortFree(psPlaneDistort *pt)
+{
+    psFree(pt->x);
+    psFree(pt->y);
+}
+
+psPlaneDistort* psPlaneDistortAlloc(psS32 n1, psS32 n2, psS32 n3, psS32 n4)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n1, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n2, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n3, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(n4, NULL);
+
+    psPlaneDistort *pt = psAlloc(sizeof(psPlaneDistort));
+    pt->x = psDPolynomial4DAlloc(n1, n2, n3, n4, PS_POLYNOMIAL_ORD);
+    pt->y = psDPolynomial4DAlloc(n1, n2, n3, n4, PS_POLYNOMIAL_ORD);
+
+    p_psMemSetDeallocator(pt, (psFreeFcn) planeDistortFree);
+    return(pt);
+}
+
+/******************************************************************************
+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_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(transform->x, NULL);
+    PS_PTR_CHECK_NULL(transform->y, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial4DEval(
+                 transform->x,
+                 coords->x,
+                 coords->y,
+                 color,
+                 magnitude
+             );
+    out->y = psDPolynomial4DEval(
+                 transform->y,
+                 coords->x,
+                 coords->y,
+                 color,
+                 magnitude
+             );
+    return (out);
+}
+
+/******************************************************************************
+alpha is LONGITUDE
+delta is LATITUDE
+ 
+    alphaP: Take the target pole in the source system; calculate its LONGITUDE
+     in the target system.  That longitude is alphaP.
+    DeltaP: Take the target pole in the source system; calculate its LATITUDE
+     in the target system.  That longitude is deltaP.
+    phiP:   This is the LONGITUDE of the ascending node in the target system.
+ *****************************************************************************/
+psSphereTransform* psSphereTransformAlloc(psF64 alphaP,
+        psF64 deltaP,
+        psF64 phiP)
+{
+    psSphereTransform* tmp = (psSphereTransform* ) psAlloc(sizeof(psSphereTransform));
+
+    tmp->cosDeltaP = cos(deltaP);
+    tmp->sinDeltaP = sin(deltaP);
+    tmp->alphaP = alphaP;
+    tmp->phiP = phiP;
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Private Function.
+ 
+piNormalize(): take an input angle in radians and convert it to the range 0:PI.
+ *****************************************************************************/
+psF32 piNormalize(psF32 angle)
+{
+    while (angle < FLT_EPSILON) {
+        angle+=M_PI;
+    }
+
+    while (angle >= M_PI) {
+        angle-=M_PI;
+    }
+    return(angle);
+}
+
+/******************************************************************************
+XXX: We convert Right Ascension angles to the range 0:PI.  Is that acceptable?
+XXX: Should we do something for Declination as well?
+ *****************************************************************************/
+psSphere* psSphereTransformApply(psSphere* out,
+                                 const psSphereTransform* transform,
+                                 const psSphere* coord)
+{
+    PS_PTR_CHECK_NULL(transform, NULL);
+    PS_PTR_CHECK_NULL(coord, NULL);
+
+    if (out == NULL) {
+        out = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    psF64 alpha = coord->r;
+    psF64 delta = coord->d;
+    psF64 alphaMinusAlphaP = alpha - transform->alphaP;
+
+    psF64 eq55 = (sin(delta) * transform->cosDeltaP) -
+                 (cos(delta) * transform->sinDeltaP * sin(alphaMinusAlphaP));
+
+    psF64 eq56 = (cos(delta) * transform->cosDeltaP * sin(alphaMinusAlphaP)) +
+                 (sin(delta) * transform->sinDeltaP);
+
+    psF64 eq57 = cos(delta) * cos(alphaMinusAlphaP);
+
+    psF64 theta = asin(eq55);
+    psF64 phi = atan2(eq56, eq57) + transform->alphaP;
+
+
+    out->r = piNormalize(phi);
+    out->d = theta;
+
+    return(out);
+}
+
+psSphereTransform* psSphereTransformICRSToEcliptic(psTime *time)
+{
+    PS_PTR_CHECK_NULL(time, NULL);
+    psF64 MJD = psTimeToMJD(time);
+    struct tm *tmTime = psTimeToTM(time);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 alphaP = 0.0;
+    psF64 deltaP = DEG_TO_RAD(23.0) +
+                   SEC_TO_RAD(27.0) +
+                   MIN_TO_RAD(8.0) -
+                   (SEC_TO_RAD(46.845) * T) -
+                   (SEC_TO_RAD(0.0059) * T * T) +
+                   (SEC_TO_RAD(0.00181) * T * T * T);
+    psF64 phiP = 0.0;
+
+    psFree(tmTime);
+
+    // Don't neglect the minus sign on deltaP (bug 244):
+    return (psSphereTransformAlloc(alphaP, -deltaP, phiP));
+}
+
+
+psSphereTransform* psSphereTransformEclipticToICRS(psTime *time)
+{
+    PS_PTR_CHECK_NULL(time, NULL);
+    psF64 MJD = psTimeToMJD(time);
+    struct tm *tmTime = psTimeToTM(time);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 alphaP = 0.0;
+    psF64 deltaP = DEG_TO_RAD(23.0) +
+                   SEC_TO_RAD(27.0) +
+                   MIN_TO_RAD(8.0) -
+                   (SEC_TO_RAD(46.845) * T) -
+                   (SEC_TO_RAD(0.0059) * T * T) +
+                   (SEC_TO_RAD(0.00181) * T * T * T);
+    psF64 phiP = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+// XXX: This is bug 245: alphaP swaps with phiP from psSphereTransformGalaticToICRS()
+psSphereTransform* psSphereTransformICRSToGalatic(void)
+{
+    psF64 alphaP = DEG_TO_RAD(32.93192);
+    psF64 deltaP = DEG_TO_RAD(-62.87175);
+    psF64 phiP = DEG_TO_RAD(282.85948);
+
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+psSphereTransform* psSphereTransformGalaticToICRS(void)
+{
+    psF64 alphaP = DEG_TO_RAD(282.85948);
+    psF64 deltaP = DEG_TO_RAD(62.87175);
+    psF64 phiP = DEG_TO_RAD(32.93192);
+
+    return (psSphereTransformAlloc(alphaP, deltaP, phiP));
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: Must apply scaling at the end.
+ *****************************************************************************/
+psPlane* psProject(const psSphere* coord,
+                   const psProjection* projection)
+{
+    PS_PTR_CHECK_NULL(coord, NULL);
+    PS_PTR_CHECK_NULL(projection, NULL);
+
+    psPlane* tmp = (psPlane* ) psAlloc(sizeof(psPlane));
+    if (projection->type == PS_PROJ_TAN) {
+
+        /*
+                // ********************************************
+                // From the ADD
+                // ********************************************
+                // psLogMsg(__func__, PS_LOG_WARN, "WARNING: psProject(): These projections don't work.");
+                // return(NULL);
+                psF32 sinTheta;
+                psF32 cosThetaCosPhi;
+                psF32 cosThetaSinPhi;
+         
+                sinTheta = (sin(coord->d) * sin(projection->D)) + 
+                           (cos(coord->d) * cos(projection->D) * (cos(coord->r - projection->R)));
+                cosThetaCosPhi = (sin(coord->d) * cos(projection->D)) - 
+                                 (cos(coord->d) * sin(projection->D) * (cos(coord->r - projection->R)));
+                cosThetaSinPhi = - cos(coord->d) * sin(coord->r - projection->R);
+         
+                tmp->x =  -cosThetaSinPhi / sinTheta;
+                tmp->y = cosThetaCosPhi / sinTheta;
+         
+        */
+        // ********************************************
+        // From the mathworks: http://mathworld.wolfram.com/GnomonicProjection.html
+        // delta_0 and phi_1 are the projection centers, not the point being projected.
+        // (delta_0, phi_1) == (projection->R, projection->D)
+        // ********************************************
+        psF32 cosC = (sin(projection->D) * sin(coord->d)) +
+                     (cos(projection->D) * cos(coord->d) * cos(coord->r - projection->R));
+        tmp->x = (cos(coord->d) * sin(coord->r - projection->R)) / cosC;
+        tmp->y = ((cos(projection->D) * sin(coord->d)) -
+                  (sin(projection->D) * cos(coord->d) * cos(coord->r - projection->R))) /
+                 cosC;
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        // psLogMsg(__func__, PS_LOG_WARN, "WARNING: psProject(): These projections don't work.");
+        // return(NULL);
+
+        tmp->x = cos(coord->d) * sin(coord->d);
+        tmp->y = -cos(coord->d) * 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(DEG_TO_RAD(45.0) + (0.5 * coord->r)));
+    } else if (projection->type == PS_PROJ_AIT) {
+        psF64 tmpF64  = PS_SQRT_F32(0.5 * (1.0 + (cos(coord->r) * cos(0.5 * coord->d))));
+        tmpF64 = 1.0 / tmpF64;
+        tmp->x = 2.0 * tmpF64 * cos(coord->r) * sin(0.5 * coord->d);
+        tmp->y = sin(coord->r) * tmpF64;
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_PAR");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_GLS");
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
+                projection->type);
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Waiting for algorithms.
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: Must apply scaling at the beginning.
+ *****************************************************************************/
+psSphere* psDeproject(const psPlane* coord,
+                      const psProjection* projection)
+{
+    PS_PTR_CHECK_NULL(coord, NULL);
+    PS_PTR_CHECK_NULL(projection, NULL);
+    //    psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): These projections don't work.");
+    //    return(NULL);
+    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) {
+        /*
+                // ********************************************
+                // From the ADD
+                // ********************************************
+                psF32 phi;
+                psF32 theta;
+                psF32 sinDelta;
+                psF32 cosDeltaCosAlphaMinusAlphaP;
+                psF32 cosDeltaSinAlphaMinusAlphaP;
+         
+                phi = atan2(-coord->y, coord->x);
+                R = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+                theta = atan(1.0 / R);
+         
+                sinDelta = (sin(theta) * sin(projection->D)) + 
+                           (cos(theta) * cos(projection->D) * cos(phi));
+                cosDeltaCosAlphaMinusAlphaP = 
+                           (sin(theta) * cos(projection->D)) - 
+                           (cos(theta) * sin(projection->D) * cos(phi));
+                cosDeltaSinAlphaMinusAlphaP = -cos(theta) * sin(phi);
+                tmp->d = asin(sinDelta);
+                tmp->r = atan2(cosDeltaSinAlphaMinusAlphaP, cosDeltaCosAlphaMinusAlphaP) + projection->R;
+        */
+        // ********************************************
+        // From the mathworks: http://mathworld.wolfram.com/GnomonicProjection.html
+        // delta_0 and phi_1 are the projection centers, not the point being projected.
+        // (delta_0, phi_1) == (projection->R, projection->D)
+        // XXX: figure out how to use the two-argument atan2() here.
+        // ********************************************
+        psF32 row = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+        psF32 C = atan(row);
+        tmp->d = asin((cos(C) * sin(projection->D)) +
+                      ((coord->y * sin(C) * cos(projection->D)) / row));
+        psF32 tmpAtan = atan((coord->x * sin(C)) /
+                             ((row * cos(projection->D) * cos(C)) -
+                              (coord->y * sin(projection->D) * sin(C))));
+        tmp->r = projection->R + tmpAtan;
+
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = PS_SQRT_F32((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = atan2(-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 = PS_SQRT_F32(1.0 - chu1 - chu2);
+        tmp->d = 2.0 * atan2((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) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_PAR");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED,
+                "PS_PROJ_GLS");
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN,
+                projection->type);
+    }
+
+    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_PTR_CHECK_NULL(position1, NULL);
+    PS_PTR_CHECK_NULL(position2, NULL);
+
+    if (position1->d >= DEG_TO_RAD(90.0)) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): position1->d is larger than 90 degrees.  Returning NULL.\n");
+        return(NULL);
+    }
+    if (position2->d >= DEG_TO_RAD(90.0)) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: psDeproject(): position2->d is larger than 90 degrees.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    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(position1, &proj);
+        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 = RAD_TO_SEC(tmp->r);
+            tmp->d = RAD_TO_SEC(tmp->d);
+        } else if (unit == PS_ARCMIN) {
+            tmp->r = RAD_TO_MIN(tmp->r);
+            tmp->d = RAD_TO_MIN(tmp->d);
+        } else if (unit == PS_DEGREE) {
+            tmp->r = RAD_TO_DEG(tmp->r);
+            tmp->d = RAD_TO_DEG(tmp->d);
+        } else if (unit == PS_RADIAN) {}
+        else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psCoord_UNITS_UNKNOWN,
+                    unit);
+            psFree(tmp);
+            return(NULL);
+        }
+
+        return (tmp);
+    }
+
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+            PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN,
+            mode);
+    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_PTR_CHECK_NULL(position, NULL);
+    PS_PTR_CHECK_NULL(offset, NULL);
+
+    psPlane lin;
+    psSphere* tmp;
+    psProjection proj;
+    psF64 tmpR = 0.0;
+    psF64 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 = SEC_TO_RAD(offset->r);
+            tmpD = SEC_TO_RAD(offset->d);
+        } else if (unit == PS_ARCMIN) {
+            tmpR = MIN_TO_RAD(offset->r);
+            tmpD = MIN_TO_RAD(offset->d);
+        } else if (unit == PS_DEGREE) {
+            tmpR = DEG_TO_RAD(offset->r);
+            tmpD = DEG_TO_RAD(offset->d);
+        } else if (unit == PS_RADIAN) {
+            tmpR = offset->r;
+            tmpD = offset->d;
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psCoord_UNITS_UNKNOWN,
+                    unit);
+            return(NULL);
+        }
+
+        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);
+    }
+
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+            PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN,
+            mode);
+
+    return (NULL);
+}
+
+
+
+/******************************************************************************
+psSpherePrecess(coords, fromTime, toTime):
+ 
+XXX: Use static memory for tmpST.
+ *****************************************************************************/
+psSphere *psSpherePrecess(psSphere *coords,
+                          const psTime *fromTime,
+                          const psTime *toTime)
+{
+    psF64 fromMJD = psTimeToMJD(fromTime);
+    psF64 toMJD = psTimeToMJD(toTime);
+    psF64 T = (toMJD - fromMJD) / 36525.0;
+
+    psF64 alphaP = DEG_TO_RAD(90.0) - ((DEG_TO_RAD(0.6406161) * T) +
+                                       (DEG_TO_RAD(0.0000839) * T * T) +
+                                       (DEG_TO_RAD(0.000005) * T * T * T));
+
+    psF64 deltaP = (DEG_TO_RAD(0.5567530) * T) -
+                   (DEG_TO_RAD(0.0001185) * T * T) -
+                   (DEG_TO_RAD(0.0000116) * T * T * T);
+
+    psF64 phiP = DEG_TO_RAD(90.0) - ((DEG_TO_RAD(0.6406161) * T) +
+                                     (DEG_TO_RAD(0.0003041) * T * T) +
+                                     (DEG_TO_RAD(0.0000051) * T * T * T));
+
+    psSphereTransform *tmpST = psSphereTransformAlloc(alphaP, deltaP, phiP);
+
+    psSphere *out = psSphereTransformApply(NULL, tmpST, coords);
+
+    psFree(tmpST);
+
+    return(out);
+}
+
Index: /branches/rel4/psLib/src/astronomy/psCoord.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psCoord.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psCoord.h	(revision 3057)
@@ -0,0 +1,326 @@
+/** @file  psCoord.h
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-08 18:23:54 $
+*
+*  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 alphaP;                    ///< Longitude of the target system pole in the source system
+    double cosDeltaP;                 ///< Cosine of target pole latitude in the source system
+    double sinDeltaP;                 ///< Sine of target pole latitude in the source system
+    double phiP;                      ///< Longitude of the ascending node in the target system
+}
+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;
+
+/** Allocates a psPlaneTransform transform.
+ *
+ *  @return psPlaneTransform*     resulting plane transform
+ */
+
+psPlaneTransform* psPlaneTransformAlloc(
+    psS32 n1,  ///< The order of the x term in the transform.
+    psS32 n2   ///< The order of the y term in the transform.
+);
+
+/** 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.
+);
+
+/** Allocates a psPlaneDistort transform.
+ *
+ *  @return psPlaneDistort*     resulting plane distort transform
+ */
+
+psPlaneDistort* psPlaneDistortAlloc(
+    psS32 n1,  ///< The order of the w term in the transform.
+    psS32 n2,  ///< The order of the x term in the transform.
+    psS32 n3,  ///< The order of the y term in the transform.
+    psS32 n4   ///< The order of the z term in the transform.
+);
+
+
+/** 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 alphaP,                      ///< north pole latitude
+    double deltaP,                      ///< north pole longitude?
+    double phiP                         ///< defines the longitude in the input system of the equatorial intersection between the two systems (e.g, the first point of Ares).
+);
+
+/** 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
+);
+
+psSphere *psSpherePrecess(psSphere *coords,
+                          const psTime *fromTime,
+                          const psTime *toTime);
+
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/psMetadata.c
===================================================================
--- /branches/rel4/psLib/src/astronomy/psMetadata.c	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psMetadata.c	(revision 3057)
@@ -0,0 +1,513 @@
+
+/** @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.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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 "psLookupTable.h"
+#include "psString.h"
+#include "psAstronomyErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static psS32 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);
+    if (type != PS_META_PRIMITIVE) {
+        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, psElemType pType, 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, pType, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psElemType pType, psMetadataType type,
+                                     const char *comment, va_list argPtr)
+{
+    psMetadataItem* metadataItem = NULL;
+
+
+    PS_PTR_CHECK_NULL(name,NULL);
+
+    // Allocate metadata item
+    metadataItem = (psMetadataItem*) psAlloc(sizeof(psMetadataItem));
+    metadataItem->data.V = NULL;
+
+    // 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
+    *(psS32 *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+    metadataItem->pType = pType;
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Set metadata item value
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            metadataItem->data.B = (psBool)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_S32:
+            metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_F32:
+            metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+            break;
+        case PS_TYPE_F64:
+            metadataItem->data.F64 = (psF64)va_arg(argPtr, psF64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+            psFree(metadataItem);
+            metadataItem = NULL;
+        }
+        break;
+    case PS_META_STR:
+        // Perform copy of input strings
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_LIST:
+    case PS_META_VEC:
+    case PS_META_HASH:
+    case PS_META_LOOKUPTABLE:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        // Copy of input data not performed due to variability of data types
+        metadataItem->data.V = va_arg(argPtr, psPtr);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+        psFree(metadataItem);
+        metadataItem = 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;
+}
+
+psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location)
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+    PS_PTR_CHECK_NULL(metadataItem,NULL);
+    PS_PTR_CHECK_NULL(metadataItem->name,NULL);
+
+    newType = metadataItem->type;
+    mdTable = md->table;
+    mdList = md->list;
+    key = metadataItem->name;
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_LIST) {
+
+            if(existingEntry->data.list == NULL) {
+                existingEntry->data.list = psListAlloc(NULL);
+            }
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED, metadataItem->name);
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_LIST && newType!= PS_META_LIST) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_TYPE_PTR, PS_META_LIST, NULL, NULL);
+            newFolderEntry->data.list = psListAlloc(NULL);
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,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(metadataItem->data.list == NULL) {
+                metadataItem->data.list = psListAlloc(NULL);
+            }
+
+            if(!psListAdd(metadataItem->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_LIST metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_LIST) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name, psElemType pType,
+                     psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, pType, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_FAILED);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key)
+{
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    mdList = md->list;
+    mdTable = md->table;
+
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem*)psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_FAILED, key);
+            return false;
+        }
+
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+            return false;
+        }
+
+        key = entry->name;
+        if(key == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED, where);
+            return false;
+        }
+    }
+
+    if (!psListRemoveData(mdList, entry)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
+        return false;
+    }
+
+    // Remove entry from metadata collection's table
+    if (!psHashRemove(mdTable, key)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
+        return false;
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata *md, const char *key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(key,NULL);
+
+    mdTable = md->table;
+    entry = (psMetadataItem*)psHashLookup(mdTable, key);
+
+    return entry;
+}
+
+void* psMetadataLookupPtr(psMetadata *md, const char *key, psBool *status)
+{
+    psMetadataItem *metadataItem = NULL;
+
+    if (status) {
+        *status = true;
+    }
+
+    metadataItem = psMetadataLookup(md, key);
+    if(metadataItem == NULL) {
+        if (status) {
+            *status = false;
+        }
+        return NULL;
+    }
+
+    if(metadataItem->type == PS_META_PRIMITIVE && metadataItem->pType != PS_TYPE_PTR) {
+        if (status) {
+            *status = false;
+        }
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH,
+                metadataItem->pType,
+                PS_TYPE_PTR);
+        return NULL;
+    } else {
+        return metadataItem->data.V;
+    }
+}
+
+#define psMetadataLookupNumTYPE(TYPE) \
+ps##TYPE psMetadataLookup##TYPE(psMetadata *md, const char *key, psBool *status) \
+{ \
+    psMetadataItem *metadataItem = NULL; \
+    \
+    if (status) { \
+        *status = true; \
+    } \
+    \
+    metadataItem = psMetadataLookup(md, key); \
+    if(metadataItem == NULL) { \
+        if (status) { \
+            *status = false; \
+        } \
+        return 0; \
+    } \
+    \
+    if (metadataItem->type == PS_META_PRIMITIVE) { \
+        switch (metadataItem->pType) { \
+        case PS_TYPE_S32: \
+            return metadataItem->data.S32; \
+        case PS_TYPE_F32: \
+            return metadataItem->data.F32; \
+        case PS_TYPE_F64: \
+            return metadataItem->data.F64; \
+        case PS_TYPE_BOOL: \
+            if (metadataItem->data.B) { \
+                return 1; \
+            } \
+            return 0; \
+        default: \
+            break; \
+        } \
+    } \
+    \
+    /* if you get to this point, the value is not a number. */ \
+    if (status) { \
+        *status = false; \
+    } \
+    \
+    return 0; \
+}
+
+psMetadataLookupNumTYPE(F32)
+psMetadataLookupNumTYPE(F64)
+psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
+
+psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
+{
+    psMetadataItem* entry = NULL;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    entry = (psMetadataItem*) psListGet(md->list, where);
+    if (entry == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+        return NULL;
+    }
+
+    return entry;
+}
Index: /branches/rel4/psLib/src/astronomy/psMetadata.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psMetadata.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psMetadata.h	(revision 3057)
@@ -0,0 +1,284 @@
+
+/** @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.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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_PRIMITIVE,                 ///< Primitive data.
+    PS_META_LIST,                      ///< List data (Stored as item.data.list).
+    PS_META_STR,                       ///< String data (Stored as item.data.V).
+    PS_META_VEC,                       ///< Vector data (Stored as item.data.V).
+    PS_META_IMG,                       ///< Image data (Stored as item.data.V).
+    PS_META_HASH,                      ///< Hash data (Stored as item.data.V).
+    PS_META_LOOKUPTABLE,               ///< Lookup table data (Stored as item.data.V).
+    PS_META_JPEG,                      ///< JPEG data (Stored as item.data.V).
+    PS_META_PNG,                       ///< PNG data (Stored as item.data.V).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored as item.data.V).
+    PS_META_UNKNOWN,                   ///< Other data (Stored as item.data.V).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** 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*  list;                     ///< Metadata in linked-list
+    psHash*  table;                    ///< Metadata in a hash table
+}
+psMetadata;
+
+/** 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 psS32 id;                    ///< Unique ID for metadata item.
+    char *name;                        ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    psElemType pType;                  ///< Primitive data type
+    union {
+        psBool B;                      ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psList *list;                  ///< List data.
+        psMetadata *md;                ///< Metadata data.
+        psPtr V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+}
+psMetadataItem;
+
+/** 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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+ */
+psBool psMetadataAddItem(
+    psMetadata*  md,          ///< Metadata collection to insert metadat item.
+    psMetadataItem*  item,    ///< Metadata item to be added.
+    psS32 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.
+ */
+psBool psMetadataAdd(
+    psMetadata* md,           ///< Metadata collection to insert metadat item.
+    psS32 where,              ///< Location to be added.
+    const char *name,         ///< Name of metadata item.
+    psElemType pType,         ///< Primitive type.
+    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.
+ */
+psBool psMetadataRemove(
+    psMetadata*  md,           ///< Metadata collection to remove metadata item.
+    psS32 where,               ///< Location to be removed.
+    const char * 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 * md,           ///< Metadata collection to lookup metadata item.
+    const char * key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name and return its double precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF64 : Value of metadata item.
+ */
+psF64 psMetadataLookupF64(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its single precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF32 : Value of metadata item.
+ */
+psF32 psMetadataLookupF32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psS32 : Value of metadata item.
+ */
+psS32 psMetadataLookupS32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return void* : Value of metadata item.
+ */
+void* psMetadataLookupPtr(
+    psMetadata* md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** 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*  md,           ///< Metadata collection to insert metadat item.
+    psS32 where                ///< Location to be retrieved.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/psMetadataIO.c
===================================================================
--- /branches/rel4/psLib/src/astronomy/psMetadataIO.c	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psMetadataIO.c	(revision 3057)
@@ -0,0 +1,1127 @@
+/** @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.18 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 20:48:59 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <libxml/parser.h>
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.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"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR)                                                                          \
+fits_get_errstatus(status, fitsErr);                                                                         \
+psError(PS_ERR_IO,true, STRING, PS_ERROR, fitsErr);                                                          \
+status = 0;                                                                                                  \
+fits_close_file(fd, &status);                                                                                \
+if(status){                                                                                                  \
+    fits_get_errstatus(status, fitsErr);                                                                     \
+    psError(PS_ERR_IO,true, "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;                                                                                       \
+}
+
+/** 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                                          */
+/*****************************************************************************/
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName);
+static void p_psInitVectorXml(void *ctx, char *tagName);
+static void p_psInitMetadataItemXml(void *ctx, char *tagName);
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+psBool 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, psS32 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. */
+psS32 repeatedChars(char *inString, char ch)
+{
+    psS32 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, psS32 *status)
+{
+    char *cleanToken = NULL;
+    psS32 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, psS32 *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. */
+psBool parseBool(char *inString, psS32 *status)
+{
+    psBool 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, psS32 *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    psS32 i = 0;
+    psS32 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(PS_ERR_BAD_PARAMETER_VALUE,true,
+                        PS_ERRORTEXT_psMetadataIO_TYPE_INVALID,
+                        elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+    psElemType pType;
+    psBool success = true;
+
+    PS_PTR_CHECK_NULL(fd, success);
+    PS_PTR_CHECK_NULL(format, success);
+    PS_PTR_CHECK_NULL(metadataItem, success);
+
+    type = metadataItem->type;
+    pType = metadataItem->pType;
+
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            fprintf(fd, format, metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            fprintf(fd,format, metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            fprintf(fd, format, metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            fprintf(fd, format, metadataItem->data.F64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)pType);
+            success = false;
+        }
+        break;
+    case PS_META_STR:
+        fprintf(fd,format, (char*)metadataItem->data.V);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)type);
+        success = false;
+    }
+
+    return success;
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, psS32 extNum, char *fileName)
+{
+    psBool tempBool;
+    psBool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    psS32 i;
+    psS32 hduType = 0;
+    psS32 status = 0;
+    psS32 numKeys = 0;
+    psS32 keyNum = 0;
+    fitsfile *fd = NULL;
+
+    PS_PTR_CHECK_NULL(fileName,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 < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE,
+                extNum);
+        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':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_S32, PS_META_PRIMITIVE,
+                                    keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_F64, PS_META_PRIMITIVE,
+                                    keyComment, atof(keyValue));
+            break;
+        case 'C':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_PTR, PS_META_STR, keyComment,
+                                    keyValue);
+            break;
+        case 'L':
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_BOOL, PS_META_PRIMITIVE, keyComment,
+                                    tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID, keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadataIO_ADD_FAILED, keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    psBool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    psS32 status = 0;
+    psU32 lineCount = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType pType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    PS_PTR_CHECK_NULL(fileName,NULL);
+    if((fp=fopen(fileName, "r")) == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // 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) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount,
+                        fileName);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_LIST;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_BOOL;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F64;
+            } else {
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
+                        fileName);
+                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_LIST) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    (*nFail)++;
+                    status = 0;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
+                            fileName);
+                    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) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount,
+                        fileName);
+                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_LIST) {
+                    if(overwrite) {
+                        psMetadataRemove(md, INT_MIN, strName);
+                    } else {
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
+                                fileName);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_LIST:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+                break;
+            case PS_META_STR:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, pType, &status);
+                if(!status) {
+                    psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                            strType, lineCount, fileName);
+                    continue;
+                }
+                break;
+            case PS_META_PRIMITIVE:
+                switch (pType) {
+                case PS_TYPE_BOOL:
+                    tempBool = parseBool(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempBool);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_S32:
+                    tempInt = (psS32)parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempInt);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_F32:
+                case PS_TYPE_F64:
+                    tempDbl = parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempDbl);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true,
+                                PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount,
+                                fileName);
+                        continue;
+                    }
+                    break;
+                default:
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                            fileName);
+                    continue;
+                } // switch
+                break;
+            default:
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                        fileName);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return md;
+}
+
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)
+{
+    psU64 i = 0;
+    char* psTagName = NULL;
+    char *psAttName = NULL;
+    char *psAttValue = NULL;
+    const xmlChar *attName = NULL;
+    const xmlChar *attValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psTagName = psStringCopy(tagName);
+
+    // Metadata containter for housing element attributes used by other SAX events
+    htAtts = psHashAlloc(10);
+
+    // Get tag name
+    if(psTagName != NULL) {
+        psHashAdd(htAtts, "tagName", psTagName);
+    } else {
+        PS_PTR_CHECK_NULL_GENERAL(psTagName, return);
+        psFree(htAtts);
+        psFree(psTagName);
+        return;
+    }
+
+    // Get all attribute names and attribute values
+    if(atts != NULL) {
+        attName = atts[i++];
+        attValue = atts[i++];
+        while(attName != NULL) {
+            if(attValue != NULL) {
+
+                // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+                psAttName = psStringCopy(attName);
+                psAttValue = psStringCopy(attValue);
+                psHashAdd(htAtts, psAttName, psAttValue);
+                psFree(psAttName);
+                psFree(psAttValue);
+            } else {
+                PS_PTR_CHECK_NULL_GENERAL(psAttValue, return);
+                psFree(htAtts);
+                psFree(psTagName);
+                return;
+            }
+            attName = atts[i++];
+            attValue = atts[i++];
+        }
+    }
+
+    // Add attributes to metadata
+    psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_TYPE_PTR, PS_META_HASH, NULL, htAtts);
+
+    psFree(psTagName);
+
+    return;
+}
+
+static void p_psInitMetadataItemXml(void *ctx, char *tagName)
+{
+    psBool overwrite = false;
+    psBool tempBool = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *fileName = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *metadataItem = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    metadataItem = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem, return);
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem->data.list, return);
+    metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)metadataItem->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    // Get attribute value, if there is one
+    strValue = psHashLookup(htAtts, "value");
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    lineNumber, fileName);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Create metadata item and add to metadata
+    switch(mdType) {
+    case PS_META_LIST:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+        break;
+    case PS_META_STR:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, strValue);
+        break;
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            tempBool = parseBool((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempBool);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_S32:
+            tempInt = (psS32)parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempInt);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_F32:
+        case PS_TYPE_F64:
+            tempDbl = parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempDbl);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+        } // End switch
+        break;
+    default:
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+    } // End switch
+
+
+    return;
+}
+
+
+static void p_psInitVectorXml(void *ctx, char *tagName)
+{
+    bool overwrite = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *fileName = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psVector *vec = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    strValue = psHashLookup(htAtts, "value");
+    PS_PTR_CHECK_NULL_GENERAL(strValue, return);
+
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    input->line, input->filename);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Get value
+    vec = parseVector((char*)strValue, pType, &status);
+    if(!status) {
+        psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, NULL, vec);
+    } else {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                lineNumber, fileName);
+    }
+    psFree(vec);
+}
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName)
+{
+    char *psStartTagName = NULL;
+    char *psEndTagName = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psEndTagName = psStringCopy(tagName);
+
+    // Compare start and end tag names
+    psStartTagName = psHashLookup(htAtts, "tagName");
+    PS_PTR_CHECK_NULL_GENERAL(psStartTagName, return);
+    if(strcmp(psEndTagName, psStartTagName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName);
+    }
+
+    // Initialize psLib structs
+    if(!strcmp(psEndTagName, "psMetadataItem")) {
+        p_psInitMetadataItemXml(ctx, psEndTagName);
+    } else if(!strcmp(psEndTagName, "psVector")) {
+        p_psInitVectorXml(ctx, psEndTagName);
+    } else if(strcmp(psEndTagName, "psRoot")) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName);
+    }
+
+    // Free temporary metadata item and its hash table
+    psListRemove(tables->data.list, PS_LIST_TAIL);
+
+    psFree(psEndTagName);
+
+    return;
+}
+
+psMetadata*  psMetadataParseConfigXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    xmlSAXHandler saxHandler;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(fileName, NULL);
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Sax handler initializations
+    saxHandler.internalSubset           = NULL;
+    saxHandler.isStandalone             = NULL;
+    saxHandler.hasInternalSubset        = NULL;
+    saxHandler.hasExternalSubset        = NULL;
+    saxHandler.resolveEntity            = NULL;
+    saxHandler.getEntity                = NULL;
+    saxHandler.entityDecl               = NULL;
+    saxHandler.notationDecl             = NULL;
+    saxHandler.attributeDecl            = NULL;
+    saxHandler.elementDecl              = NULL;
+    saxHandler.unparsedEntityDecl       = NULL;
+    saxHandler.setDocumentLocator       = NULL;
+    saxHandler.startDocument            = NULL;
+    saxHandler.endDocument              = NULL;
+    saxHandler.startElement             = p_saxStartElement;
+    saxHandler.endElement               = p_saxEndElement;
+    saxHandler.reference                = NULL;
+    saxHandler.characters               = NULL;
+    saxHandler.ignorableWhitespace      = NULL;
+    saxHandler.processingInstruction    = NULL;
+    saxHandler.comment                  = NULL;
+    saxHandler.warning                  = xmlParserError;
+    saxHandler.error                    = xmlParserError;
+    saxHandler.fatalError               = xmlParserError;
+    saxHandler.getParameterEntity       = NULL;
+    saxHandler.cdataBlock               = NULL;
+    saxHandler.externalSubset           = NULL;
+    saxHandler.initialized              = 1;
+    saxHandler._private                 = md;
+    saxHandler.startElementNs           = NULL;
+    saxHandler.endElementNs             = NULL;
+    saxHandler.serror                   = NULL;
+
+    // Parse XML file
+    if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Parser and memory cleanups for libxml2
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return md;
+}
Index: /branches/rel4/psLib/src/astronomy/psMetadataIO.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psMetadataIO.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psMetadataIO.h	(revision 3057)
@@ -0,0 +1,85 @@
+/** @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.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-06 20:00:03 $
+*
+*  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.
+ */
+bool psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* 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.
+    psS32 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 psMetadata* : Resulting metadata from read.
+ */
+psMetadata* psMetadataParseConfig(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/** Read XML metadata configuration file.
+ *
+ *  Loads pre-defined XML settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return psMetadata* : Resulting metadata from read.
+ */
+
+psMetadata*  psMetadataParseConfigXml(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/psPhotometry.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psPhotometry.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psPhotometry.h	(revision 3057)
@@ -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.8 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-27 00:57:30 $
+*
+*  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 psS32 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/rel4/psLib/src/astronomy/psTime.c
===================================================================
--- /branches/rel4/psLib/src/astronomy/psTime.c	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psTime.c	(revision 3057)
@@ -0,0 +1,1166 @@
+/** @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.  They use the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-17 20:47:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#include "psTime.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psImage.h"
+#include "psCoord.h"
+#include "psString.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+#include "psLookupTable.h"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+#ifndef TIME_CONFIG_FILE
+#define TIME_CONFIG_FILE "../../config/psTime.config"
+#pragma warning TIME_CONFIG_FILE was not defined in the makefile.
+#endif
+
+#define MAX_STRING_LENGTH 256
+
+/** 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
+
+                /** Time metadata read from config file */
+                static psMetadata *timeMetadata = NULL;
+
+/** Static function prototypes */
+static char *cleanString(char *inString, int sLen);
+static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
+psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables);
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+static 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;
+}
+
+/** 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. */
+static char* getToken(char **inString, char *delimiter, psParseErrorType *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 = PS_PARSE_ERROR_GENERAL;
+    }
+
+    return cleanToken;
+}
+
+/** Searches time tables in priority order and performs interpolation if input index value is within a table.
+ * If the index value is out of range, the status is set accordingly. */
+psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables)
+{
+    psU32 i = 0;
+    char *tableName = NULL;
+    psF64 result = 0.0;
+    psLookupTable *table = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+
+
+
+    // Check time metadata. Function call reports errors.
+    if(timeMetadata == NULL) {
+        if(!p_psTimeInit(TIME_CONFIG_FILE))
+            return 0.0;
+    }
+
+    // Search each table in priority order: ser7, eopc,finals
+    for(i=0; i<nTables; i++) {
+
+        // Get table from metadata
+        tableName = metadataTableNames[i];
+        tableMetadataItem = psMetadataLookup(timeMetadata, tableName);
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                    tableName);
+            return 0.0;
+        }
+        table = (psLookupTable*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(table,0.0);
+
+        // Attempt to interpolate table
+        *status = PS_LOOKUP_SUCCESS;
+        result = psLookupTableInterpolate(table, index, 2, status);
+        if(*status == PS_LOOKUP_SUCCESS) {
+            return result;
+        } else if(*status == PS_LOOKUP_ERROR) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME,
+                    tableName);
+            return 0.0;
+        }
+    }
+
+    return result;
+}
+
+bool p_psTimeInit(const char *fileName)
+{
+    bool foundTable = false;
+    char *tableDir = NULL;
+    char *tableNames = NULL;
+    char *namesPtr = NULL;
+    char *metadataNamesPtr = NULL;
+    char *tableName = NULL;
+    char *fullTableName = NULL;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 numTables = 0;
+    psU32 nFail = 0;
+    psVector *tablesFrom = NULL;
+    psVector *tablesTo = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psLookupTable *table = NULL;
+    psParseErrorType status = PS_PARSE_SUCCESS;
+    char metadataTableNames[4][MAX_STRING_LENGTH] = {"ser7", "eopc",  "finals", "tai"};
+
+
+    // Read time config file
+    timeMetadata = psMetadataParseConfig(timeMetadata, &nFail, fileName, true);
+    if(timeMetadata == NULL) {
+        return false;
+    } else if(nFail != 0) {
+        return false;
+    }
+
+    // Get number of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.n");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.n");
+        return false;
+    }
+    numTables = (psS32)metadataItem->data.S32;
+
+    // Get lower range of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.from");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.from");
+        return false;
+    }
+    tablesFrom = psVectorCopy(tablesFrom, metadataItem->data.V, PS_TYPE_F64);
+    if(tablesFrom->n != numTables) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_VECTOR, tablesFrom->n, numTables);
+        psFree(tablesFrom);
+        return false;
+    }
+
+    // Get upper range of tables
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.to");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.to");
+        return false;
+    }
+    tablesTo = psVectorCopy(tablesTo, metadataItem->data.V, PS_TYPE_F64);
+    if(tablesTo->n != numTables) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_VECTOR, tablesTo->n, numTables);
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        return false;
+    }
+
+    // Get path to time data files
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.dir");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.dir");
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        return false;
+    }
+    tableDir = psStringCopy(metadataItem->data.V);
+
+    // Table file names
+    metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.files");
+    if(metadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                "psLib.time.tables.files");
+
+        psFree(tablesFrom);
+        psFree(tablesTo);
+        psFree(tableDir);
+        return false;
+    }
+    tableNames = psStringCopy(metadataItem->data.V);
+
+    // Read time tables
+    namesPtr = tableNames;
+    while((tableName=getToken(&namesPtr, " ", &status)) != NULL) {
+
+        // Form path with table name, adding one to length for last '/' that may not occur in string in cong file
+        fullTableName = (char*)psAlloc(strlen(tableDir)+strlen(tableName)+1+1);
+
+        // Old strings may come back from psAlloc(), so set initial position to EOL
+        fullTableName[0]='\0';
+        strcat(fullTableName, tableDir);
+        strcat(fullTableName, "/");
+        strcat(fullTableName, tableName);
+
+        // Create and read table
+        if(i < numTables) {
+            table = psLookupTableAlloc(fullTableName, tablesFrom->data.F64[i], tablesTo->data.F64[i]);
+            table = psLookupTableRead(table);
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, i+1, numTables);
+        }
+
+        // Place tables into metadata slightly altered names as keys to create consistent naming conventions
+        foundTable = false;
+        for(j=0; j<numTables; j++) {
+            metadataNamesPtr = strstr(tableName, metadataTableNames[j]);
+            if(metadataNamesPtr != NULL) {
+                psMetadataAdd(timeMetadata, PS_LIST_TAIL, strcat(metadataTableNames[j], "Table"),
+                              PS_TYPE_PTR, PS_META_LOOKUPTABLE, NULL, table);
+                foundTable = true;
+            } else if(foundTable==false && j==numTables-1) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, j, numTables);
+            }
+        }
+
+        psFree(fullTableName);
+        psFree(tableName);
+        i++;
+    }
+
+    if(numTables != i) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_BAD_TABLE_COUNT, i, numTables);
+    }
+
+    psFree(tableDir);
+    psFree(tableNames);
+    psFree(tablesFrom);
+    psFree(tablesTo);
+
+    return true;
+}
+
+bool p_psTimeFinalize(void)
+{
+    if(timeMetadata != NULL) {
+        psFree(timeMetadata);
+        timeMetadata = NULL;
+    }
+
+    return true;
+}
+
+psTime* psTimeAlloc(psTimeType type)
+{
+    psTime *outTime = NULL;
+
+
+    // Error checks
+    if(type!=PS_TIME_TAI && type!=PS_TIME_UTC) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psTime_TYPE_UNKNOWN,
+                type);
+        return NULL;
+    }
+
+    outTime = (psTime*)psAlloc(sizeof(psTime));
+
+    outTime->sec = 0;
+    outTime->usec = 0;
+    outTime->type = type;
+
+    return outTime;
+}
+
+psTime* psTimeGetTime(psTimeType type)
+{
+    struct timeval now;
+    psTime *time = NULL;
+
+
+    // Allocate psTime struct
+    time = psTimeAlloc(type);
+
+    if (gettimeofday(&now, (struct timezone *)0) == -1) {
+        psError(PS_ERR_OS_CALL_FAILED, true,
+                PS_ERRORTEXT_psTime_GET_TOD_FAILED);
+        return NULL;
+    }
+
+    // Convert timeval time to psTime
+    time->sec = now.tv_sec;
+    time->usec = now.tv_usec;
+
+    // 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;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    if (time->type == type) { // time already right type.  That was easy!
+        return time;
+    }
+
+    delta = psTimeGetTAIDelta(time);
+
+    if (type == PS_TIME_UTC) {
+        time->sec = time->sec - delta;    // User wants UTC time. Subtract leapseconds.
+    } else if(type == PS_TIME_TAI) {
+        time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_UNKNOWN, 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 *tdtTime     = NULL;
+    psTime *taiTime     = NULL;
+    psTime *utcTime     = NULL;
+    psTime *ut1Time     = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // Calculate TAI or UTC time based on type of time user passes
+    if(time->type == PS_TIME_TAI) {
+        taiTime = psMemIncrRefCounter(time);
+        utcTime = psTimeAlloc(PS_TIME_UTC);
+        utcTime->sec = taiTime->sec - psTimeGetTAIDelta(time);
+        utcTime->usec = taiTime->usec;
+    } else if(time->type == PS_TIME_UTC) {
+        utcTime = psMemIncrRefCounter(time);
+        taiTime = psTimeAlloc(PS_TIME_TAI);
+        taiTime->sec = utcTime->sec + psTimeGetTAIDelta(time);
+        taiTime->usec = utcTime->usec;
+    }
+
+    // Convert Universal Time (UTC) to  UT1
+    ut1UtcDbl = psTimeGetUT1Delta(taiTime);
+    utcTime->type = PS_TIME_TAI; // Don't allow addition of leapseconds to ut1Time
+    ut1Time = psTimeMath(utcTime, ut1UtcDbl);
+    utcTime->type = PS_TIME_UTC;
+
+
+    // 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)
+    tdtTime = psTimeMath(taiTime, 32.184);
+
+    // 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(utcTime);
+    psFree(taiTime);
+
+    return lmstRad;
+}
+
+double psTimeGetUT1Delta(const psTime *time)
+{
+    psU32 nTables = 3;
+    psF64 mjd = 0.0;
+    psF64 result = 0.0;
+    psF64 dut2ut1 = 0.0;
+    psF64 t = 0.0;
+    psVector *dut = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+    psLookupStatusType status = PS_LOOKUP_SUCCESS;
+    char *metadataTableNames[3] = {"ser7Table", "eopcTable",  "finalsTable"};
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    if(time->type != PS_TIME_TAI) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_INCORRECT, time->type);
+        return 0.0;
+    }
+
+    // Attempt to find value through table lookup and interpolation
+    mjd = psTimeToMJD(time);
+    result = searchTables(mjd, 0, &status, metadataTableNames, nTables);
+
+    // Value could not be found through table lookup and interpolation
+    if(status == PS_LOOKUP_PAST_TOP) {
+
+        // Date too early for tables. Get default time delta value from metadata, and issue warning.
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES, mjd, "UT1-UTC");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.dut");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.dut");
+            return 0.0;
+        }
+        result = tableMetadataItem->data.F64;
+
+    } else if(status == PS_LOOKUP_PAST_BOTTOM) {
+        /* Date too late for tables. Issue warning and use following formulae for predicting
+           ahead of the most recent available table entry.
+             ut1-utc = [0] + [1]*(MJD - [2]) - (ut2-ut1)
+             [0, 1, 2] = @psLib.time.predict.dut
+             ut2-ut1 = 0.022 sin(2*pi*t) - 0.012 cos(2*pi*t) - 0.006 sin(4*pi*t) + 0.007 cos(4*pi*t)
+             t = 2000.0 + (MJD - 51544.03)/365.2422
+        */
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES, mjd, "UT1-UTC");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.dut");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.dut");
+            return 0.0;
+        }
+        dut = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(dut,0.0);
+
+        t = 2000.0 + (mjd - 51544.03)/365.2422;
+        dut2ut1 = 0.022*sin(TWOPI*t) - 0.012*cos(TWOPI*t) - 0.006*sin(4.0*M_PI*t) + 0.007*cos(4.0*M_PI*t);
+        result = dut->data.F64[0] + dut->data.F64[1]*(mjd - dut->data.F64[2]) - dut2ut1;
+
+    } else if(status != PS_LOOKUP_SUCCESS) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        return 0.0;
+    }
+
+    return result;
+}
+
+struct psSphere* psTimeGetPoleCoords(const psTime* time)
+{
+    psU32 nTables = 3;
+    psF64 x = 0.0;
+    psF64 y = 0.0;
+    psF64 mjd = 0.0;
+    psF64 a = 0.0;
+    psF64 c = 0.0;
+    psF64 mjdPred = 0.0;
+    struct psSphere* output = NULL;
+    psLookupStatusType xStatus = PS_LOOKUP_SUCCESS;
+    psLookupStatusType yStatus = PS_LOOKUP_SUCCESS;
+    psMetadataItem *tableMetadataItem = NULL;
+    char *metadataTableNames[3] = {"ser7Table", "eopcTable",  "finalsTable"};
+    psVector *xp = NULL;
+    psVector *yp = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    if(time->type != PS_TIME_TAI)
+    {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_INCORRECT, time->type);
+        return NULL;
+    }
+
+    // Attempt to find value through table lookup and interpolation
+    mjd = psTimeToMJD(time);
+    x = searchTables(mjd, 0, &xStatus, metadataTableNames, nTables);
+    y = searchTables(mjd, 0, &yStatus, metadataTableNames, nTables);
+
+    // Value could not be found through table lookup and interpolation
+    if(xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP)
+    {
+
+        // Date too earlier for tables. Get default polar coodinate values from metadata, and issue warning.
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES, mjd, "polar motion");
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.xp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.xp");
+            return NULL;
+        }
+        x = tableMetadataItem->data.F64;
+
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.yp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.before.yp");
+            return NULL;
+        }
+        y = tableMetadataItem->data.F64;
+
+    } else if(xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM)
+    {
+
+        /* Date too late for tables. Issue warning and use following formulae for predicting
+           ahead of the most recent available table entry.
+              x = [0] + [1]*cos a + [2]*sin a + [3]*cos c + [4]*sin c
+              [0], [1], [2], [3] = @psLib.time.predict.xp
+              y = [0] + [1]*cos a + [2]*sin a + [3]*cos c + [4]*sin c
+              [0], [1], [2], [3] = @psLib.time.predict.yp
+              a = 2*pi*(mjd - pslib.time.predict.mjd)/365.25
+              c = 2*pi*(mjd - pslib.time.predict.mjd)/435.0
+        */
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES, mjd, "polar motion");
+
+
+        // Get predicted MJD
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.mjd");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED,
+                    "psLib.time.predict.mjd");
+            return NULL;
+        }
+        mjdPred = tableMetadataItem->data.F64;
+
+        // Get xp
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.xp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.xp");
+            return NULL;
+        }
+        xp = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(xp,NULL);
+
+        // Get yp
+        tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.yp");
+        if(tableMetadataItem == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "psLib.time.predict.yp");
+            return NULL;
+        }
+        yp = (psVector*)tableMetadataItem->data.V;
+        PS_PTR_CHECK_NULL(yp,NULL);
+
+        // Calculate "a" and "c" constants
+        a = TWOPI*(mjd - mjdPred)/365.25;
+        c = TWOPI*(mjd - mjdPred)/435.0;
+
+        // Calculate x and y polar coordinates
+        x = xp->data.F64[0] +
+            xp->data.F64[1]*cos(a) +
+            xp->data.F64[2]*sin(a) +
+            xp->data.F64[3]*cos(c) +
+            xp->data.F64[4]*sin(c);
+
+        y = yp->data.F64[0] +
+            yp->data.F64[1]*cos(a) +
+            yp->data.F64[2]*sin(a) +
+            yp->data.F64[3]*cos(c) +
+            yp->data.F64[4]*sin(c);
+
+    } else if(xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS)
+    {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        return NULL;
+    }
+
+    // Create output sphere and convert arcsec to radians (i.e. x/60/60*M_PI/180)
+    output = psAlloc(sizeof(psSphere));
+    output->r = x * M_PI / 648000.0;
+    output->d = y * M_PI / 648000.0;
+
+    return output;
+}
+
+double psTimeGetTAIDelta(const psTime *time)
+{
+    psU64 i = 0;
+    psF64 jd = 0.0;
+    psF64 mjd = 0.0;
+    psF64 out = 0.0;
+    psF64 const1 = 0.0;
+    psF64 const2 = 0.0;
+    psF64 const3 = 0.0;
+    psLookupTable* table = NULL;
+    psMetadataItem *tableMetadataItem = NULL;
+    psVector *stats = NULL;
+    psVector *results = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // Check time metadata
+    if(timeMetadata == NULL) {
+        if(!p_psTimeInit(TIME_CONFIG_FILE)) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_FILE_NOT_FOUND, "psTime.config");
+            return 0.0;
+        }
+    }
+
+    // Get table from metadata
+    tableMetadataItem = psMetadataLookup(timeMetadata, "taiTable");
+    if(tableMetadataItem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED, "taiTable");
+        return 0.0;
+    }
+    table = (psLookupTable*)tableMetadataItem->data.V;
+    PS_PTR_CHECK_NULL(table,0);
+
+    // Determine Julian and modified Julian dates used in table lookup and time delta calculation
+    jd = psTimeToJD(time);
+    mjd = psTimeToMJD(time);
+
+    stats = psVectorAlloc(table->numCols, PS_TYPE_U32);
+    results = psLookupTableInterpolateAll(table, jd, stats);
+
+    // Check for successful interpolation
+    for(i=0; i<stats->n; i++) {
+        if(stats->data.U32[i] == PS_LOOKUP_ERROR) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
+        }
+    }
+
+    const1 = results->data.F64[0];
+    const2 = results->data.F64[1];
+    const3 = results->data.F64[2];
+    out = const1 + (mjd - const2) * const3;
+
+    psFree(stats);
+    psFree(results);
+
+    return out;
+}
+
+
+psS64 psTimeLeapseconds(const psTime *time1, const psTime *time2)
+{
+    psS64 diff = 0;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time1,0);
+    PS_PTR_CHECK_NULL(time2,0);
+    PS_INT_CHECK_RANGE(time1->usec,0,1e6-1,0);
+    PS_INT_CHECK_RANGE(time2->usec,0,1e6-1,0);
+    diff = abs((psS64)psTimeGetTAIDelta((psTime*)time1)-(psS64)psTimeGetTAIDelta((psTime*)time2));
+
+    return diff;
+}
+
+double psTimeToJD(const psTime *time)
+{
+    double jd = 0.0;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // 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;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NAN);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NAN);
+
+    // 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)
+{
+    psS32 ms = 0;
+    char *timeString = NULL;
+    char *tempString = NULL;
+    struct tm *tmTime = NULL;
+    time_t sec;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,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(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED);
+    }
+
+    if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
+        psError(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED);
+    }
+    psFree(tempString);
+
+    return timeString;
+}
+
+struct timeval psTimeToTimeval(const psTime *time)
+{
+    struct timeval timevalTime;
+
+    timevalTime.tv_sec = 0;
+    timevalTime.tv_usec = 0;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,timevalTime);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,timevalTime);
+
+    timevalTime.tv_sec = time->sec;
+    timevalTime.tv_usec = time->usec;
+
+    return timevalTime;
+}
+
+struct tm* psTimeToTM(const psTime *time)
+{
+    psS64 cent = 0;
+    psS64 year = 0;
+    psS64 month = 0;
+    psS64 day = 0;
+    psS64 hour = 0;
+    psS64 minute = 0;
+    psS64 seconds = 0;
+    psS64 temp = 0;
+    struct tm* tmTime = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,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));
+
+    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
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Julian date conversion courtesy of Eugene Magnier
+    days = time - 2440587.5;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (psS64)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (psS64)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromMJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Modified Julian date conversion courtesy of Eugene Magnier
+    days = time - 40587.0;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (psS64)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (psS64)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromISOTime(const char *time)
+{
+    psS32 millisecond;
+    struct tm tmTime;
+    psTime *outTime = NULL;
+
+    // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
+    if (sscanf(time, "%d-%d-%dT%d:%d:%d.%d", &tmTime.tm_year, &tmTime.tm_mon, &tmTime.tm_mday,
+               &tmTime.tm_hour, &tmTime.tm_min, &tmTime.tm_sec,&millisecond) < 7) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_ISOTIME_MALFORMED, time);
+        return NULL;
+    }
+
+    PS_INT_CHECK_NON_NEGATIVE(tmTime.tm_year, outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_mon,1,12,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_mday,1,31,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_hour,0,23,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_min,0,59,outTime);
+    PS_INT_CHECK_RANGE(tmTime.tm_sec,0,59,outTime);
+    PS_INT_CHECK_RANGE(millisecond,0,999,outTime);
+
+    tmTime.tm_year -= 1900;
+    tmTime.tm_mon--;
+    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;
+
+
+    // Error check
+    PS_PTR_CHECK_NULL(time,NULL);
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // Convert to psTime
+    outTime->sec = time->tv_sec;
+    outTime->usec = time->tv_usec;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeFromTM(const struct tm* time)
+{
+    psS64 year;
+    psS64 month;
+    psS64 day;
+    psS64 hour;
+    psS64 minute;
+    psS64 seconds;
+    psS64 temp;
+    psTime *outTime = NULL;
+
+
+    // Error check
+    PS_PTR_CHECK_NULL(time,NULL);
+
+    // Allocate psTime struct
+    outTime = psTimeAlloc(PS_TIME_TAI);
+
+    // 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;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    return outTime;
+}
+
+psTime* psTimeMath(const psTime *time, psF64 delta)
+{
+    psF64 sec = 0.0;
+    psTime *outTime = NULL;
+    psTime *tempTime = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time->type == PS_TIME_UTC) {
+        tempTime = psTimeAlloc(PS_TIME_UTC);
+        tempTime->sec = time->sec;
+        tempTime->usec = time->usec;
+        tempTime = psTimeConvert(tempTime, PS_TIME_TAI);
+    } else {
+        tempTime = psMemIncrRefCounter((psTime*)time);
+    }
+
+    // Create output time
+    outTime = psTimeAlloc(PS_TIME_TAI);
+    sec = delta + (psF64)tempTime->sec + (psF64)tempTime->usec/1e6;
+    outTime->sec = sec;
+    outTime->usec = (sec - outTime->sec)*1e6;
+
+    // Error check
+    PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
+
+    // Convert result to same time type as input
+    if(time->type == PS_TIME_UTC) {
+        outTime = psTimeConvert(outTime, PS_TIME_UTC);
+    }
+
+    psFree(tempTime);
+
+    return outTime;
+}
+
+psF64 psTimeDelta(const psTime *time1, const psTime *time2)
+{
+    psF64 out = 0.0;
+    psF64 uSec1 = 0.0;
+    psF64 uSec2 = 0.0;
+    psTime *tempTime1 = NULL;
+    psTime *tempTime2 = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time1,0.0);
+    PS_INT_CHECK_RANGE(time1->usec,0,1e6-1,0.0);
+    PS_PTR_CHECK_NULL(time2,0.0);
+    PS_INT_CHECK_RANGE(time2->usec,0,1e6-1,0.0);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time1->type == PS_TIME_UTC) {
+        tempTime1 = psTimeAlloc(PS_TIME_UTC);
+        tempTime1->sec = time1->sec;
+        tempTime1->usec = time1->usec;
+        tempTime1 = psTimeConvert(tempTime1, PS_TIME_TAI);
+    } else {
+        tempTime1 = psMemIncrRefCounter((psTime*)time1);
+    }
+    if(time2->type == PS_TIME_UTC) {
+        tempTime2 = psTimeAlloc(PS_TIME_UTC);
+        tempTime2->sec = time2->sec;
+        tempTime2->usec = time2->usec;
+        tempTime2 = psTimeConvert(tempTime2, PS_TIME_TAI);
+    } else {
+        tempTime2 = psMemIncrRefCounter((psTime*)time2);
+    }
+
+    uSec1 = tempTime1->sec >= 0 ? 1.0 : -1.0;
+    uSec1 = uSec1*tempTime1->usec/1e6;
+    uSec2 = tempTime2->sec >= 0 ? 1.0 : -1.0;
+    uSec2 = uSec2*tempTime2->usec/1e6;
+    out = (tempTime1->sec-tempTime2->sec) + (uSec1-uSec2);
+
+    psFree(tempTime1);
+    psFree(tempTime2);
+
+    return out;
+}
+
Index: /branches/rel4/psLib/src/astronomy/psTime.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/psTime.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/psTime.h	(revision 3057)
@@ -0,0 +1,288 @@
+/** @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.  They use the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-16 18:52:51 $
+ *
+ *  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;
+
+
+/** Initialize time data.
+ *
+ * Reads config and data files associated with various time conversions.
+ *
+ * @return  bool: True for success, false for failure.
+ */
+psBool p_psTimeInit(const char *fileName);
+
+/** Free memory persistant time data.
+ *
+ * Frees time data to be held in memory until the end of successful program execution.
+ *
+ * @return  void: void.
+ */
+psBool p_psTimeFinalize(void);
+
+/** Allocate time struct.
+ *
+ * Allocates an empty time struct. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in the argument.
+ * The seconds and microseconds members of the struct are set to zero.
+ *
+ * @return  psTime*: Struct with empty time.
+ */
+psTime* psTimeAlloc(
+    psTimeType type                     ///< Type of time to create (UTC or TAI).
+);
+
+/** 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  psS64: leapseconds added between given times
+ */
+psS64 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.
+);
+
+/** Adds delta to time. Result is in TAI time.
+ *
+ *  Adds delta to time. Input time is converted to TAI format if necessary.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeMath(
+    const psTime *time,                 ///< Time.
+    psF64 delta                         ///< Time delta.
+);
+
+/** Determine difference between two times. Result is in TAI time.
+ *
+ *  Determine difference between two times. Input times are converted to TAI format if necessary.
+ *
+ *  @return psF64: Time difference.
+ */
+psF64 psTimeDelta(
+    const psTime *time1,                ///< First time.
+    const psTime *time2                 ///< Second time.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/astronomy/slalib.h
===================================================================
--- /branches/rel4/psLib/src/astronomy/slalib.h	(revision 3057)
+++ /branches/rel4/psLib/src/astronomy/slalib.h	(revision 3057)
@@ -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/rel4/psLib/src/collections/.cvsignore
===================================================================
--- /branches/rel4/psLib/src/collections/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/src/collections/.cvsignore	(revision 3057)
@@ -0,0 +1,1 @@
+*.i
Index: /branches/rel4/psLib/src/collections/Makefile
===================================================================
--- /branches/rel4/psLib/src/collections/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/collections/Makefile	(revision 3057)
@@ -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/rel4/psLib/src/collections/psArray.c
===================================================================
--- /branches/rel4/psLib/src/collections/psArray.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psArray.c	(revision 3057)
@@ -0,0 +1,158 @@
+
+/** @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.22 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-30 20:18:36 $
+ *
+ *  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);
+
+static void arrayFree(psArray* restrict psArr)
+{
+    if (psArr == NULL) {
+        return;
+    }
+
+    psArrayElementFree(psArr);
+
+    psFree(psArr->data);
+}
+
+/*****************************************************************************
+  FUNCTION IMPLEMENTATION - PUBLIC
+ *****************************************************************************/
+psArray* psArrayAlloc(psU32 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, psU32 nalloc)
+{
+    if (in == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL,true,PS_ERRORTEXT_psArray_REALLOC_NULL);
+        return NULL;
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        if (nalloc < in->n) {
+            for (psS32 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;
+}
+
+psArray* psArrayAdd(psArray* psArr,
+                    int delta,
+                    psPtr data)
+{
+    if (psArr == NULL) {
+        return psArr;
+    }
+
+    int n = psArr->n;
+
+    if (n >= psArr->nalloc) {
+        // array needs to be expanded to make room for more elements
+        int d = (delta > 0) ? delta : 10; // as spec'ed in SDRS.
+        psArr = psArrayRealloc(psArr, n+d);
+    }
+
+    // add the element to the end of the array.
+    psArr->data[n] = data;
+    psArr->n = n+1;
+
+    return psArr;
+}
+
+psBool psArrayRemove(psArray* psArr,
+                     psPtr data)
+{
+    psBool success = false;
+
+    if (psArr == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psArray_ARRAY_NULL);
+        return false;
+    }
+
+    psS32 n = psArr->n;
+    psPtr* psArrData = psArr->data;
+    for (psS32 i = n-1; i >= 0; i--) {
+        if (psArrData[i] == data) {
+            memmove(&psArr->data[i],&psArr->data[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 (psS32 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/rel4/psLib/src/collections/psArray.h
===================================================================
--- /branches/rel4/psLib/src/collections/psArray.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psArray.h	(revision 3057)
@@ -0,0 +1,130 @@
+
+/** @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.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 01:14:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ARRAY_H
+#define PS_ARRAY_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
+{
+    psU32 nalloc;        ///< Total number of elements available.
+    psU32 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(
+    psU32 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.
+    psU32 nalloc                       ///< Total number of elements to make available.
+);
+
+/** Add an element to the end the array, expanding the array storage if
+ *  necessary.
+ *
+ *  @return psArray*        The array with the element added
+ */
+psArray* psArrayAdd(
+    psArray* psArr,                    ///< array to operate on
+    int delta,
+    ///< the amount to expand array, if necessary.  If less than one, 10 will be used.
+    psPtr data                         ///< the data pointer to add to psArray
+);
+
+/** 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.
+ *
+ */
+psBool 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/rel4/psLib/src/collections/psBitSet.c
===================================================================
--- /branches/rel4/psLib/src/collections/psBitSet.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psBitSet.c	(revision 3057)
@@ -0,0 +1,306 @@
+/** @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.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:04:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.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(psS32 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(psS32 n)
+{
+    psS32 numBytes = 0;
+    psBitSet* newObj = NULL;
+
+    if (n < 0) {
+        psError(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,
+                      psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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,
+                        psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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;
+}
+
+psBool psBitSetTest(const psBitSet* inBitSet,
+                    psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return false;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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)
+{
+    psS32 i = 0;
+    psS32 n = 0;
+    char* outBits = NULL;
+    char* inBits1 = NULL;
+    char* inBits2 = NULL;
+    psS32 op = UNKNOWN_OP;
+
+    if (inBitSet1 == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+    inBits1 = inBitSet1->bits;
+
+    if (operator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_OPERATOR_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    // make operator all caps
+    psS32 tempStrLen = strlen(operator);
+    char* tempStr = psAlloc(tempStrLen+1);
+
+    for (psS32 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);
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psBitSet_OPERATOR_INVALID,
+                operator);
+        return NULL;
+    }
+    psFree(tempStr);
+
+    if (op != NOT_OP) {
+        if (inBitSet2 == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                    PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL);
+            psFree(outBitSet);
+            return NULL;
+        }
+
+        if (inBitSet1->n != inBitSet2->n) {
+            psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    outBitSet = psBitSetOp(outBitSet,inBitSet,"NOT",NULL);
+
+    if (outBitSet == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                PS_ERRORTEXT_psBitSet_NOT_OP_FAILED);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet* restrict inBitSet)
+{
+    psS32 i = 0;
+    psS32 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/rel4/psLib/src/collections/psBitSet.h
===================================================================
--- /branches/rel4/psLib/src/collections/psBitSet.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psBitSet.h	(revision 3057)
@@ -0,0 +1,145 @@
+/** @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.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+#include "psType.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
+{
+    psS32 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(
+    psS32 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.
+    psS32 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.
+    psS32 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.
+ */
+
+psBool psBitSetTest(
+    const psBitSet* restrict inMask,   ///< Pointer psBitSet to be tested.
+    psS32 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/rel4/psLib/src/collections/psCollectionsErrors.dat
===================================================================
--- /branches/rel4/psLib/src/collections/psCollectionsErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psCollectionsErrors.dat	(revision 3057)
@@ -0,0 +1,42 @@
+#
+#  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
+####################################################################
+#
+psArray_REALLOC_NULL                   psArrayRealloc must be given a non-NULL psArray to resize.
+psArray_ARRAY_NULL                     Specified psArray can not be NULL.
+#
+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.
+#
+psList_LOCATION_INVALID                Specified location, %d, is invalid.
+psList_ITERATOR_INVALID                Specified iterator is not valid.
+psList_ITERATOR_NULL                   Specified iterator is NULL.
+psList_LIST_NULL                       Specified psList reference is NULL.
+psList_DATA_NULL                       Specified data item is NULL.
+psList_DATA_NOT_FOUND                  Specified data item is not found in the psList.
+
Index: /branches/rel4/psLib/src/collections/psCollectionsErrors.h
===================================================================
--- /branches/rel4/psLib/src/collections/psCollectionsErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psCollectionsErrors.h	(revision 3057)
@@ -0,0 +1,61 @@
+/** @file  psCollectionsErrors.h
+ *
+ *  @brief Contains the error text for the collections functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-30 20:18:36 $
+ *
+ *  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_psArray_REALLOC_NULL "psArrayRealloc must be given a non-NULL psArray to resize."
+#define PS_ERRORTEXT_psArray_ARRAY_NULL "Specified psArray can not be NULL."
+#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."
+#define PS_ERRORTEXT_psList_LOCATION_INVALID "Specified location, %d, is invalid."
+#define PS_ERRORTEXT_psList_ITERATOR_INVALID "Specified iterator is not valid."
+#define PS_ERRORTEXT_psList_ITERATOR_NULL "Specified iterator is NULL."
+#define PS_ERRORTEXT_psList_LIST_NULL "Specified psList reference is NULL."
+#define PS_ERRORTEXT_psList_DATA_NULL "Specified data item is NULL."
+#define PS_ERRORTEXT_psList_DATA_NOT_FOUND "Specified data item is not found in the psList."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/collections/psCompare.c
===================================================================
--- /branches/rel4/psLib/src/collections/psCompare.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psCompare.c	(revision 3057)
@@ -0,0 +1,79 @@
+
+/** @file psCompare.c
+ *  @brief Comparison functions for sorting routines
+ *  @ingroup Compare
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#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/rel4/psLib/src/collections/psCompare.h
===================================================================
--- /branches/rel4/psLib/src/collections/psCompare.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psCompare.h	(revision 3057)
@@ -0,0 +1,508 @@
+/** @file psCompare.h
+ *  @brief Comparison functions for sorting routines
+ *
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup Compare
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_COMPARE_H)
+#define PS_COMPARE_H
+
+#include "psType.h"
+
+/** @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/rel4/psLib/src/collections/psHash.c
===================================================================
--- /branches/rel4/psLib/src/collections/psHash.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psHash.c	(revision 3057)
@@ -0,0 +1,466 @@
+
+/** @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
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-03 20:28:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "psHash.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psTrace.h"
+#include "psError.h"
+
+#include "psCollectionsErrors.h"
+
+static psHashBucket* hashBucketAlloc(const char *key, psPtr data, psHashBucket* next);
+static void hashBucketFree(psHashBucket* bucket);
+static psPtr doHashWork(psHash* table, const char *key, psPtr data, psBool 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)
+{
+    psS32 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,
+                                     psPtr 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(psS32 nbucket)        // initial number of buckets
+{
+    psS32 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;
+}
+
+/******************************************************************************
+hashFree(table): 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)
+{
+    psS32 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 psPtr doHashWork(psHash* table,
+                        const char *key,
+                        psPtr data, psBool remove
+                           )
+{
+    psS64 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)) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    // NOTE: This is the originally supplied hash function.
+    // for (psS32 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)) {
+        psError(PS_ERR_UNKNOWN, true,
+                "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.
+
+                    psPtr 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;
+    }
+}
+
+/******************************************************************************
+psHashAdd(table, key, data): 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.
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+psBool psHashAdd(psHash* table,
+                 const char *key,
+                 psPtr data)
+{
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_DATA_NULL);
+        return false;
+    }
+
+    return (doHashWork(table, key, data, false) != 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.
+ *****************************************************************************/
+psPtr psHashLookup(psHash* table,      // table to lookup key in
+                   const char *key)     // key to lookup
+{
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+
+    return doHashWork(table, key, NULL, false);
+}
+
+/******************************************************************************
+psHashRemove(table, key): 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
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+psBool psHashRemove(psHash* table,
+                    const char *key)
+{
+    psPtr data = NULL;
+    psBool retVal = false;
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+
+    data = doHashWork(table, key, NULL, true);
+    if (data != NULL) {
+        retVal = true;
+    } else {
+        retVal = false;
+    }
+
+    return retVal;
+}
+
+psArray* psHashToArray(psHash* table)
+{
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+
+    // first, let's just count the number of data elements to know what size
+    // psArray we need to allocate.
+    int nElements = 0;
+    int nbucket = table->nbucket;
+    for (int i = 0; i < nbucket; i++) {
+        psHashBucket* tmpBucket = table->buckets[i];
+        while (tmpBucket != NULL) {
+            nElements++;
+            tmpBucket = tmpBucket->next;
+        }
+    }
+
+    psArray* result = psArrayAlloc(nElements);
+    result->n = nElements;
+
+    // now fill in the array with the hash table's data
+    psPtr* data = result->data;
+    for (int i = 0; i < nbucket; i++) {
+        psHashBucket* tmpBucket = table->buckets[i];
+        while (tmpBucket != NULL) {
+            *(data++) = psMemIncrRefCounter(tmpBucket->data);
+            tmpBucket = tmpBucket->next;
+        }
+    }
+
+    return result;
+}
Index: /branches/rel4/psLib/src/collections/psHash.h
===================================================================
--- /branches/rel4/psLib/src/collections/psHash.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psHash.h	(revision 3057)
@@ -0,0 +1,86 @@
+
+/** @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
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-03 20:28:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_HASH_H)
+#define PS_HASH_H
+
+/** \addtogroup HashTable
+ *  \{
+ */
+
+#include "psList.h"
+
+/** A bucket that holds an item of data. */
+typedef struct psHashBucket
+{
+    char *key;                         ///< key for this item of data
+    psPtr 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
+{
+    psS32 nbucket;                     ///< Number of buckets in hash table.
+    psHashBucket* *buckets;            ///< The bucket data.
+}
+psHash;
+
+/// Allocate hash buckets in table.
+psHash* psHashAlloc(
+    psS32 nbucket                  ///< The number of buckets to allocate.
+);
+
+/// Insert entry into table.
+psBool psHashAdd(
+    psHash* table,                 ///< table to insert in
+    const char *key,               ///< key to use
+    psPtr data                     ///< data to insert
+);
+
+/// Lookup key in table.
+psPtr psHashLookup(
+    psHash* table,                 ///< table to lookup key in
+    const char *key                ///< key to lookup
+);
+
+/// Remove key from table.
+psBool 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.
+);
+
+/** Create a psArray from a psHash contents.
+ *
+ *  @return psArray*       A new psArray with duplicate contents of the input psHash
+ */
+psArray* psHashToArray(
+    psHash* table                  ///< table to convert to psArray
+);
+
+/* \} */// End of DataGroup Functions
+
+#endif
Index: /branches/rel4/psLib/src/collections/psList.c
===================================================================
--- /branches/rel4/psLib/src/collections/psList.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psList.c	(revision 3057)
@@ -0,0 +1,601 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup LinkedList
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-11 01:24:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.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 ((psPtr )1)         // next iteration should return head
+#define ITER_INIT_TAIL ((psPtr )2)         // next iteration should return tail
+
+// private functions.
+static void listFree(psList* list);
+static void listIteratorFree(psListIterator* iter);
+static psBool listIteratorRemove(psListIterator* iterator);
+
+static void listFree(psList* list)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // remove the free function of iterators to avoid double removal from list
+    psArray* iterators = list->iterators;
+    for (int i = 0; i < iterators->n; i++) {
+        p_psMemSetDeallocator(iterators->data[i], NULL);
+    }
+
+    psFree(list->iterators);
+
+    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)
+    ;
+
+}
+
+static void listIteratorFree(psListIterator* iter)
+{
+    if (iter == NULL) {
+        return;
+    }
+
+    // remove this iterator from the parent list
+    psArrayRemove(iter->list->iterators,iter);
+
+}
+
+static psBool listIteratorRemove(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return false;
+    }
+
+    psListElem* elem = iterator->cursor;
+    psList* list = iterator->list;
+    int index = iterator->index;
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (elem == list->head) {        // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem == list->tail) {        // tail of list?
+        list->tail = elem->prev;
+    } else {
+        elem->next->prev = elem->prev;
+    }
+
+    psArray* iterators = list->iterators;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->cursor == elem) {
+            iter->cursor = NULL;
+        } else if (iter->index > index && iter->index > 0) {
+            iter->index--;
+        }
+    }
+
+    list->size--;
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    // OK, delete orphaned list element and its data
+    psFree(elem->data);
+    psFree(elem);
+
+    return true;
+}
+
+psList* psListAlloc(psPtr data)
+{
+    psList* list = psAlloc(sizeof(psList));
+
+    p_psMemSetDeallocator(list, (psFreeFcn) listFree);
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iterators = psArrayAlloc(16);
+    list->iterators->n = 0;
+
+    // create a default iterator
+    psListIteratorAlloc(list,PS_LIST_HEAD);
+
+    pthread_mutex_init(&(list->lock), NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, PS_LIST_TAIL, data);
+    }
+
+    return list;
+}
+
+psListIterator* psListIteratorAlloc(psList* list, int location)
+{
+    psListIterator* iter = psAlloc(sizeof(psListIterator));
+
+    p_psMemSetDeallocator(iter, (psFreeFcn) listIteratorFree);
+
+    // initialize the attributes
+    iter->list = list;
+    iter->cursor = NULL;
+    iter->index = 0;
+    iter->offEnd = false;
+
+    // add to the list's array of iterators
+    psArray* listIterators = list->iterators;
+    int num = listIterators->n;
+    if ( num >= listIterators->nalloc) {
+        // need to resize the array to make more room for another iterator.
+        list->iterators = psArrayRealloc(listIterators,listIterators->nalloc*2);
+        listIterators = list->iterators;
+    }
+    listIterators->data[num] = iter;
+    listIterators->n = num+1;
+
+    if (! psListIteratorSet(iter,location)) {
+        psFree(iter);
+        iter = NULL;
+    }
+
+    return iter;
+}
+
+psBool psListIteratorSet(psListIterator* iterator,
+                         int location)
+{
+    if (iterator == NULL) {
+        return false;
+    }
+
+    psList* list = iterator->list;
+
+    if (location == PS_LIST_TAIL) {
+        iterator->cursor = list->tail;
+        iterator->index = list->size - 1;
+        iterator->offEnd = false;
+        return true;
+    }
+
+    if (location == PS_LIST_HEAD) {
+        iterator->cursor = list->head;
+        iterator->index = 0;
+        iterator->offEnd = false;
+        return true;
+    }
+
+    if (location < 0 || location >= (int)list->size) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_LOCATION_INVALID,
+                location);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    int index = iterator->index;
+    if (cursor == NULL) {      // set the cursor to the head if it is NULL
+        if (location > list->size/2) { // closer to tail or head?
+            cursor = list->tail;
+            index = list->size - 1;
+        } else {
+            cursor = list->head;
+            index = 0;
+        }
+    }
+
+    if (location < index) {
+        psS32 diff = index - location;
+
+        for (psS32 count = 0; count < diff; count++) {
+            cursor = cursor->prev; // shouldn't need to check for NULL
+        }
+    } else {
+        psS32 diff = location - index;
+
+        for (psS32 count = 0; count < diff; count++) {
+            cursor = cursor->next; // shouldn't need to check for NULL
+        }
+    }
+    iterator->cursor = cursor;
+    iterator->index = location;
+    iterator->offEnd = false;
+
+    return true;
+}
+
+psBool psListAdd(psList* list, psS32 location, psPtr data)
+{
+
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (location > 0 && location >= (int)list->size) {
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "Specified location, %d, is beyond the end of the list.  "
+                 "Adding data item to tail.",
+                 location);
+        location = PS_LIST_TAIL;
+    }
+
+    // move ourselves to the given position
+    if (! psListIteratorSet(list->iterators->data[0],location)) {
+        return false;
+    }
+
+    if (location == PS_LIST_TAIL) {
+        // insert the element at the end of the list
+        return psListAddAfter(list->iterators->data[0],data);
+    } else {
+        return psListAddBefore(list->iterators->data[0],data);
+    }
+}
+
+bool psListAddAfter(psListIterator* iterator, void* data)
+{
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (iterator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_ITERATOR_NULL);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    psList* list = iterator->list;
+
+    if (cursor == NULL && list->head != NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_ITERATOR_INVALID);
+        return false;
+    }
+
+    psListElem* elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // set the new list element's attributes
+    if (cursor == NULL) { // must be an empty list
+        elem->prev = NULL;
+        elem->next = NULL;
+        list->head = elem;
+        list->tail = elem;
+    } else {
+        elem->prev = cursor;
+        elem->next = cursor->next;
+        cursor->next = elem;
+        if (elem->next == NULL) {
+            list->tail = elem;
+        } else {
+            elem->next->prev = elem;
+        }
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    list->size++;
+
+    if (cursor == list->tail) {
+        list->tail = elem;
+    }
+
+    psArray* iterators = list->iterators;
+    int index = iterator->index;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->index > index) {
+            iter->index++;
+        }
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+bool psListAddBefore(psListIterator* iterator, void* data)
+{
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (iterator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_ITERATOR_NULL);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    psList* list = iterator->list;
+
+    if (cursor == NULL && list->head != NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_ITERATOR_INVALID);
+        return false;
+    }
+
+    psListElem* elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // set the new list element's attributes
+    if (cursor == NULL) { // empty list.
+        elem->prev = NULL;
+        elem->next = NULL;
+        list->head = elem;
+        list->tail = elem;
+    } else {
+        elem->prev = cursor->prev;
+        elem->next = cursor;
+        cursor->prev = elem;
+        if (elem->prev == NULL) {
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    list->size++;
+
+    if (cursor == list->head) {
+        list->head = elem;
+    }
+
+    psArray* iterators = list->iterators;
+    int index = iterator->index;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->index >= index) {
+            iter->index++;
+        }
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+psBool psListRemove(psList* list,
+                    psS32 location)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    // move ourselves to the given position
+    psListIterator* defaultIterator = list->iterators->data[0];
+    if (! psListIteratorSet(defaultIterator,location)) {
+        return false;
+    }
+
+    return listIteratorRemove(defaultIterator);
+}
+
+psBool psListRemoveData(psList* list,
+                        psPtr data)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    psListElem* elem = list->head;
+    int index = 0;
+    while (elem != NULL && elem->data != data) {
+        elem = elem->next;
+        index++;
+    }
+    if (elem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NOT_FOUND);
+        return false;
+    }
+
+    psListIterator* iterator = (psListIterator*)list->iterators->data[0];
+    iterator->index = index;
+    iterator->cursor = elem;
+
+    return listIteratorRemove(iterator);
+}
+
+psPtr psListGet(psList* list, psS32 location)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return NULL;
+    }
+
+    if (list->head == NULL) { // list empty?
+        return NULL;
+    }
+
+    psListIterator* iterator = list->iterators->data[0];
+
+    if (! psListIteratorSet(iterator,location)) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_LOCATION_INVALID,
+                location);
+        return NULL;
+    }
+
+    return iterator->cursor->data;
+}
+
+/*
+ * and now return the previous/next element of the list
+ */
+psPtr psListGetNext(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return NULL;
+    }
+
+    psPtr data = iterator->cursor->data;
+
+    iterator->cursor = iterator->cursor->next;
+    iterator->index++;
+    if (iterator->cursor == NULL) {
+        iterator->offEnd = true;
+    }
+
+    return data;
+}
+
+psPtr psListGetPrevious(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return NULL;
+    }
+
+    psPtr data = iterator->cursor->data;
+
+    iterator->cursor = iterator->cursor->prev;
+    iterator->index--;
+
+    return data;
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psArray* psListToArray(psList* restrict list)
+{
+    psListElem* ptr;
+    psU32 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 (psS32 i = 0; i < n; i++) {
+        arr->data[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psArrayToList(psArray* arr)
+{
+    psU32 n;
+    psList* list;               // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (psS32 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);
+    psArray* iterators = psMemIncrRefCounter(list->iterators);
+    psFree(list);
+
+    arr = psArraySort(arr, compare);
+
+    // convert back to linked list
+    list = psArrayToList(arr);
+    psFree(list->iterators);
+    list->iterators = iterators;
+    psFree(arr);
+
+    // sorting should invalidate all iterator positions.
+    for (int i = 0; i < iterators->n; i++) {
+        ((psListIterator*)iterators->data[i])->cursor = NULL;
+    }
+
+    return list;
+}
Index: /branches/rel4/psLib/src/collections/psList.h
===================================================================
--- /branches/rel4/psLib/src/collections/psList.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psList.h	(revision 3057)
@@ -0,0 +1,226 @@
+#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.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-10 02:50:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#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
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem* prev;           ///< previous link in list
+    struct psListElem* next;           ///< next link in list
+    psPtr 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
+ */
+typedef struct
+{
+    psU32 size;                        ///< number of elements on list
+    psListElem* head;                  ///< first element on list (may be NULL)
+    psListElem* tail;                  ///< last element on list (may be NULL)
+    psArray* iterators;
+    ///< array of all iterators associated with this list.  First iterator is
+    ///< used internally to improve performance when using indexed access, all
+    ///< others are user-level iterators created by psListIteratorAlloc.
+
+    pthread_mutex_t lock;              ///< mutex to lock a node during changes
+}
+psList;
+
+/** The psList iterator structure.  This should be allocated via
+ *  psListIteratorAlloc and not directly.
+ *
+ *  The life span of a psListIterator object is ended by either a psFree
+ *  of this structure OR psFree of the psList in which it operates on.
+ *
+ *  @see psListIteratorAlloc, psListIteratorSet, psListGetNext, psListGetPrevious
+ */
+typedef struct
+{
+psList* list;                      ///< List iterator to works on
+psListElem* cursor;                ///< current cursor position
+int index;                         ///< the index number in the list
+bool offEnd;                       ///< Iterator off the end?
+}
+psListIterator;
+
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList* A new psList object.
+ */
+psList* psListAlloc(
+    psPtr data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+/** Creates a psListIterator object and associates it with a psList.
+ *
+ *  @return psListIterator* A new psListIterator object.
+ */
+psListIterator* psListIteratorAlloc(
+    psList* list,                      ///< the psList to iterate with
+    int location                       ///< the initial starting point.
+    ///<  This can be a numeric index, PS_LIST_HEAD, or PS_LIST_TAIL.
+);
+
+/** Set the iterator of the list to a given position.  If location is invalid the
+ *  iterator position is not changed.
+ *
+ *  @return psBool        TRUE if iterator successfully set, otherwise FALSE.
+ */
+psBool psListIteratorSet(
+    psListIterator* iterator,            ///< list iterator
+    int location                         ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAdd(
+    psList* restrict list,             ///< list to add item to
+    psS32 location,                    ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Adds an data item to a psList at position just after the list position given
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAddAfter(
+    psListIterator* list,              ///< list position to add item to
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Adds an data item to a psList at position just before the list position given
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAddBefore(
+    psListIterator* list,              ///< list position to add item to
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Remove an item at the specified location from a list.
+ *
+ *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+psBool psListRemove(
+    psList* restrict list,             ///< list to remove element from
+    psS32 location                     ///< index of item
+);
+
+/** Remove an item from a list.
+ *
+ *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+psBool psListRemoveData(
+    psList* restrict list,             ///< list to remove element from
+    psPtr data                         ///< data item to find and remove
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return psPtr       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.
+ */
+psPtr psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    psS32 location                     ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Position the specified iterator to the next item in list.
+ *
+ *  @return psPtr       the data item at the new iterator position or NULL if the
+ *                      iterator goes past the end of the list.
+ */
+psPtr psListGetNext(
+    psListIterator* restrict iterator  ///< iterator to move
+);
+
+/** Position the specified iterator to the previous item in list.
+ *
+ *  @return psPtr       the data item at the new iterator position or NULL if the
+ *                      iterator goes past the beginning of the list.
+ */
+psPtr psListGetPrevious(
+    psListIterator* restrict iterator  ///< iterator to move
+);
+
+/** 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/rel4/psLib/src/collections/psMetadata.c
===================================================================
--- /branches/rel4/psLib/src/collections/psMetadata.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psMetadata.c	(revision 3057)
@@ -0,0 +1,513 @@
+
+/** @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.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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 "psLookupTable.h"
+#include "psString.h"
+#include "psAstronomyErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static psS32 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);
+    if (type != PS_META_PRIMITIVE) {
+        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, psElemType pType, 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, pType, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psElemType pType, psMetadataType type,
+                                     const char *comment, va_list argPtr)
+{
+    psMetadataItem* metadataItem = NULL;
+
+
+    PS_PTR_CHECK_NULL(name,NULL);
+
+    // Allocate metadata item
+    metadataItem = (psMetadataItem*) psAlloc(sizeof(psMetadataItem));
+    metadataItem->data.V = NULL;
+
+    // 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
+    *(psS32 *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+    metadataItem->pType = pType;
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Set metadata item value
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            metadataItem->data.B = (psBool)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_S32:
+            metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_F32:
+            metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+            break;
+        case PS_TYPE_F64:
+            metadataItem->data.F64 = (psF64)va_arg(argPtr, psF64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+            psFree(metadataItem);
+            metadataItem = NULL;
+        }
+        break;
+    case PS_META_STR:
+        // Perform copy of input strings
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_LIST:
+    case PS_META_VEC:
+    case PS_META_HASH:
+    case PS_META_LOOKUPTABLE:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        // Copy of input data not performed due to variability of data types
+        metadataItem->data.V = va_arg(argPtr, psPtr);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+        psFree(metadataItem);
+        metadataItem = 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;
+}
+
+psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location)
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+    PS_PTR_CHECK_NULL(metadataItem,NULL);
+    PS_PTR_CHECK_NULL(metadataItem->name,NULL);
+
+    newType = metadataItem->type;
+    mdTable = md->table;
+    mdList = md->list;
+    key = metadataItem->name;
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_LIST) {
+
+            if(existingEntry->data.list == NULL) {
+                existingEntry->data.list = psListAlloc(NULL);
+            }
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED, metadataItem->name);
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_LIST && newType!= PS_META_LIST) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_TYPE_PTR, PS_META_LIST, NULL, NULL);
+            newFolderEntry->data.list = psListAlloc(NULL);
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,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(metadataItem->data.list == NULL) {
+                metadataItem->data.list = psListAlloc(NULL);
+            }
+
+            if(!psListAdd(metadataItem->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_LIST metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_LIST) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name, psElemType pType,
+                     psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, pType, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_FAILED);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key)
+{
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    mdList = md->list;
+    mdTable = md->table;
+
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem*)psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_FAILED, key);
+            return false;
+        }
+
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+            return false;
+        }
+
+        key = entry->name;
+        if(key == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED, where);
+            return false;
+        }
+    }
+
+    if (!psListRemoveData(mdList, entry)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
+        return false;
+    }
+
+    // Remove entry from metadata collection's table
+    if (!psHashRemove(mdTable, key)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
+        return false;
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata *md, const char *key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(key,NULL);
+
+    mdTable = md->table;
+    entry = (psMetadataItem*)psHashLookup(mdTable, key);
+
+    return entry;
+}
+
+void* psMetadataLookupPtr(psMetadata *md, const char *key, psBool *status)
+{
+    psMetadataItem *metadataItem = NULL;
+
+    if (status) {
+        *status = true;
+    }
+
+    metadataItem = psMetadataLookup(md, key);
+    if(metadataItem == NULL) {
+        if (status) {
+            *status = false;
+        }
+        return NULL;
+    }
+
+    if(metadataItem->type == PS_META_PRIMITIVE && metadataItem->pType != PS_TYPE_PTR) {
+        if (status) {
+            *status = false;
+        }
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH,
+                metadataItem->pType,
+                PS_TYPE_PTR);
+        return NULL;
+    } else {
+        return metadataItem->data.V;
+    }
+}
+
+#define psMetadataLookupNumTYPE(TYPE) \
+ps##TYPE psMetadataLookup##TYPE(psMetadata *md, const char *key, psBool *status) \
+{ \
+    psMetadataItem *metadataItem = NULL; \
+    \
+    if (status) { \
+        *status = true; \
+    } \
+    \
+    metadataItem = psMetadataLookup(md, key); \
+    if(metadataItem == NULL) { \
+        if (status) { \
+            *status = false; \
+        } \
+        return 0; \
+    } \
+    \
+    if (metadataItem->type == PS_META_PRIMITIVE) { \
+        switch (metadataItem->pType) { \
+        case PS_TYPE_S32: \
+            return metadataItem->data.S32; \
+        case PS_TYPE_F32: \
+            return metadataItem->data.F32; \
+        case PS_TYPE_F64: \
+            return metadataItem->data.F64; \
+        case PS_TYPE_BOOL: \
+            if (metadataItem->data.B) { \
+                return 1; \
+            } \
+            return 0; \
+        default: \
+            break; \
+        } \
+    } \
+    \
+    /* if you get to this point, the value is not a number. */ \
+    if (status) { \
+        *status = false; \
+    } \
+    \
+    return 0; \
+}
+
+psMetadataLookupNumTYPE(F32)
+psMetadataLookupNumTYPE(F64)
+psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
+
+psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
+{
+    psMetadataItem* entry = NULL;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    entry = (psMetadataItem*) psListGet(md->list, where);
+    if (entry == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+        return NULL;
+    }
+
+    return entry;
+}
Index: /branches/rel4/psLib/src/collections/psMetadata.h
===================================================================
--- /branches/rel4/psLib/src/collections/psMetadata.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psMetadata.h	(revision 3057)
@@ -0,0 +1,284 @@
+
+/** @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.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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_PRIMITIVE,                 ///< Primitive data.
+    PS_META_LIST,                      ///< List data (Stored as item.data.list).
+    PS_META_STR,                       ///< String data (Stored as item.data.V).
+    PS_META_VEC,                       ///< Vector data (Stored as item.data.V).
+    PS_META_IMG,                       ///< Image data (Stored as item.data.V).
+    PS_META_HASH,                      ///< Hash data (Stored as item.data.V).
+    PS_META_LOOKUPTABLE,               ///< Lookup table data (Stored as item.data.V).
+    PS_META_JPEG,                      ///< JPEG data (Stored as item.data.V).
+    PS_META_PNG,                       ///< PNG data (Stored as item.data.V).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored as item.data.V).
+    PS_META_UNKNOWN,                   ///< Other data (Stored as item.data.V).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** 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*  list;                     ///< Metadata in linked-list
+    psHash*  table;                    ///< Metadata in a hash table
+}
+psMetadata;
+
+/** 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 psS32 id;                    ///< Unique ID for metadata item.
+    char *name;                        ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    psElemType pType;                  ///< Primitive data type
+    union {
+        psBool B;                      ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psList *list;                  ///< List data.
+        psMetadata *md;                ///< Metadata data.
+        psPtr V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+}
+psMetadataItem;
+
+/** 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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+ */
+psBool psMetadataAddItem(
+    psMetadata*  md,          ///< Metadata collection to insert metadat item.
+    psMetadataItem*  item,    ///< Metadata item to be added.
+    psS32 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.
+ */
+psBool psMetadataAdd(
+    psMetadata* md,           ///< Metadata collection to insert metadat item.
+    psS32 where,              ///< Location to be added.
+    const char *name,         ///< Name of metadata item.
+    psElemType pType,         ///< Primitive type.
+    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.
+ */
+psBool psMetadataRemove(
+    psMetadata*  md,           ///< Metadata collection to remove metadata item.
+    psS32 where,               ///< Location to be removed.
+    const char * 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 * md,           ///< Metadata collection to lookup metadata item.
+    const char * key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name and return its double precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF64 : Value of metadata item.
+ */
+psF64 psMetadataLookupF64(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its single precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF32 : Value of metadata item.
+ */
+psF32 psMetadataLookupF32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psS32 : Value of metadata item.
+ */
+psS32 psMetadataLookupS32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return void* : Value of metadata item.
+ */
+void* psMetadataLookupPtr(
+    psMetadata* md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** 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*  md,           ///< Metadata collection to insert metadat item.
+    psS32 where                ///< Location to be retrieved.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/collections/psMetadataIO.c
===================================================================
--- /branches/rel4/psLib/src/collections/psMetadataIO.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psMetadataIO.c	(revision 3057)
@@ -0,0 +1,1127 @@
+/** @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.18 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 20:48:59 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <libxml/parser.h>
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.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"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR)                                                                          \
+fits_get_errstatus(status, fitsErr);                                                                         \
+psError(PS_ERR_IO,true, STRING, PS_ERROR, fitsErr);                                                          \
+status = 0;                                                                                                  \
+fits_close_file(fd, &status);                                                                                \
+if(status){                                                                                                  \
+    fits_get_errstatus(status, fitsErr);                                                                     \
+    psError(PS_ERR_IO,true, "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;                                                                                       \
+}
+
+/** 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                                          */
+/*****************************************************************************/
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName);
+static void p_psInitVectorXml(void *ctx, char *tagName);
+static void p_psInitMetadataItemXml(void *ctx, char *tagName);
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+psBool 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, psS32 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. */
+psS32 repeatedChars(char *inString, char ch)
+{
+    psS32 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, psS32 *status)
+{
+    char *cleanToken = NULL;
+    psS32 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, psS32 *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. */
+psBool parseBool(char *inString, psS32 *status)
+{
+    psBool 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, psS32 *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    psS32 i = 0;
+    psS32 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(PS_ERR_BAD_PARAMETER_VALUE,true,
+                        PS_ERRORTEXT_psMetadataIO_TYPE_INVALID,
+                        elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+    psElemType pType;
+    psBool success = true;
+
+    PS_PTR_CHECK_NULL(fd, success);
+    PS_PTR_CHECK_NULL(format, success);
+    PS_PTR_CHECK_NULL(metadataItem, success);
+
+    type = metadataItem->type;
+    pType = metadataItem->pType;
+
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            fprintf(fd, format, metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            fprintf(fd,format, metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            fprintf(fd, format, metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            fprintf(fd, format, metadataItem->data.F64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)pType);
+            success = false;
+        }
+        break;
+    case PS_META_STR:
+        fprintf(fd,format, (char*)metadataItem->data.V);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)type);
+        success = false;
+    }
+
+    return success;
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, psS32 extNum, char *fileName)
+{
+    psBool tempBool;
+    psBool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    psS32 i;
+    psS32 hduType = 0;
+    psS32 status = 0;
+    psS32 numKeys = 0;
+    psS32 keyNum = 0;
+    fitsfile *fd = NULL;
+
+    PS_PTR_CHECK_NULL(fileName,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 < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE,
+                extNum);
+        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':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_S32, PS_META_PRIMITIVE,
+                                    keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_F64, PS_META_PRIMITIVE,
+                                    keyComment, atof(keyValue));
+            break;
+        case 'C':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_PTR, PS_META_STR, keyComment,
+                                    keyValue);
+            break;
+        case 'L':
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_BOOL, PS_META_PRIMITIVE, keyComment,
+                                    tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID, keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadataIO_ADD_FAILED, keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    psBool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    psS32 status = 0;
+    psU32 lineCount = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType pType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    PS_PTR_CHECK_NULL(fileName,NULL);
+    if((fp=fopen(fileName, "r")) == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // 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) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount,
+                        fileName);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_LIST;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_BOOL;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F64;
+            } else {
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
+                        fileName);
+                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_LIST) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    (*nFail)++;
+                    status = 0;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
+                            fileName);
+                    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) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount,
+                        fileName);
+                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_LIST) {
+                    if(overwrite) {
+                        psMetadataRemove(md, INT_MIN, strName);
+                    } else {
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
+                                fileName);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_LIST:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+                break;
+            case PS_META_STR:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, pType, &status);
+                if(!status) {
+                    psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                            strType, lineCount, fileName);
+                    continue;
+                }
+                break;
+            case PS_META_PRIMITIVE:
+                switch (pType) {
+                case PS_TYPE_BOOL:
+                    tempBool = parseBool(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempBool);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_S32:
+                    tempInt = (psS32)parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempInt);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_F32:
+                case PS_TYPE_F64:
+                    tempDbl = parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempDbl);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true,
+                                PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount,
+                                fileName);
+                        continue;
+                    }
+                    break;
+                default:
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                            fileName);
+                    continue;
+                } // switch
+                break;
+            default:
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                        fileName);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return md;
+}
+
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)
+{
+    psU64 i = 0;
+    char* psTagName = NULL;
+    char *psAttName = NULL;
+    char *psAttValue = NULL;
+    const xmlChar *attName = NULL;
+    const xmlChar *attValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psTagName = psStringCopy(tagName);
+
+    // Metadata containter for housing element attributes used by other SAX events
+    htAtts = psHashAlloc(10);
+
+    // Get tag name
+    if(psTagName != NULL) {
+        psHashAdd(htAtts, "tagName", psTagName);
+    } else {
+        PS_PTR_CHECK_NULL_GENERAL(psTagName, return);
+        psFree(htAtts);
+        psFree(psTagName);
+        return;
+    }
+
+    // Get all attribute names and attribute values
+    if(atts != NULL) {
+        attName = atts[i++];
+        attValue = atts[i++];
+        while(attName != NULL) {
+            if(attValue != NULL) {
+
+                // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+                psAttName = psStringCopy(attName);
+                psAttValue = psStringCopy(attValue);
+                psHashAdd(htAtts, psAttName, psAttValue);
+                psFree(psAttName);
+                psFree(psAttValue);
+            } else {
+                PS_PTR_CHECK_NULL_GENERAL(psAttValue, return);
+                psFree(htAtts);
+                psFree(psTagName);
+                return;
+            }
+            attName = atts[i++];
+            attValue = atts[i++];
+        }
+    }
+
+    // Add attributes to metadata
+    psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_TYPE_PTR, PS_META_HASH, NULL, htAtts);
+
+    psFree(psTagName);
+
+    return;
+}
+
+static void p_psInitMetadataItemXml(void *ctx, char *tagName)
+{
+    psBool overwrite = false;
+    psBool tempBool = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *fileName = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *metadataItem = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    metadataItem = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem, return);
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem->data.list, return);
+    metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)metadataItem->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    // Get attribute value, if there is one
+    strValue = psHashLookup(htAtts, "value");
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    lineNumber, fileName);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Create metadata item and add to metadata
+    switch(mdType) {
+    case PS_META_LIST:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+        break;
+    case PS_META_STR:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, strValue);
+        break;
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            tempBool = parseBool((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempBool);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_S32:
+            tempInt = (psS32)parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempInt);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_F32:
+        case PS_TYPE_F64:
+            tempDbl = parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempDbl);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+        } // End switch
+        break;
+    default:
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+    } // End switch
+
+
+    return;
+}
+
+
+static void p_psInitVectorXml(void *ctx, char *tagName)
+{
+    bool overwrite = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *fileName = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psVector *vec = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    strValue = psHashLookup(htAtts, "value");
+    PS_PTR_CHECK_NULL_GENERAL(strValue, return);
+
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    input->line, input->filename);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Get value
+    vec = parseVector((char*)strValue, pType, &status);
+    if(!status) {
+        psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, NULL, vec);
+    } else {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                lineNumber, fileName);
+    }
+    psFree(vec);
+}
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName)
+{
+    char *psStartTagName = NULL;
+    char *psEndTagName = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psEndTagName = psStringCopy(tagName);
+
+    // Compare start and end tag names
+    psStartTagName = psHashLookup(htAtts, "tagName");
+    PS_PTR_CHECK_NULL_GENERAL(psStartTagName, return);
+    if(strcmp(psEndTagName, psStartTagName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName);
+    }
+
+    // Initialize psLib structs
+    if(!strcmp(psEndTagName, "psMetadataItem")) {
+        p_psInitMetadataItemXml(ctx, psEndTagName);
+    } else if(!strcmp(psEndTagName, "psVector")) {
+        p_psInitVectorXml(ctx, psEndTagName);
+    } else if(strcmp(psEndTagName, "psRoot")) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName);
+    }
+
+    // Free temporary metadata item and its hash table
+    psListRemove(tables->data.list, PS_LIST_TAIL);
+
+    psFree(psEndTagName);
+
+    return;
+}
+
+psMetadata*  psMetadataParseConfigXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    xmlSAXHandler saxHandler;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(fileName, NULL);
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Sax handler initializations
+    saxHandler.internalSubset           = NULL;
+    saxHandler.isStandalone             = NULL;
+    saxHandler.hasInternalSubset        = NULL;
+    saxHandler.hasExternalSubset        = NULL;
+    saxHandler.resolveEntity            = NULL;
+    saxHandler.getEntity                = NULL;
+    saxHandler.entityDecl               = NULL;
+    saxHandler.notationDecl             = NULL;
+    saxHandler.attributeDecl            = NULL;
+    saxHandler.elementDecl              = NULL;
+    saxHandler.unparsedEntityDecl       = NULL;
+    saxHandler.setDocumentLocator       = NULL;
+    saxHandler.startDocument            = NULL;
+    saxHandler.endDocument              = NULL;
+    saxHandler.startElement             = p_saxStartElement;
+    saxHandler.endElement               = p_saxEndElement;
+    saxHandler.reference                = NULL;
+    saxHandler.characters               = NULL;
+    saxHandler.ignorableWhitespace      = NULL;
+    saxHandler.processingInstruction    = NULL;
+    saxHandler.comment                  = NULL;
+    saxHandler.warning                  = xmlParserError;
+    saxHandler.error                    = xmlParserError;
+    saxHandler.fatalError               = xmlParserError;
+    saxHandler.getParameterEntity       = NULL;
+    saxHandler.cdataBlock               = NULL;
+    saxHandler.externalSubset           = NULL;
+    saxHandler.initialized              = 1;
+    saxHandler._private                 = md;
+    saxHandler.startElementNs           = NULL;
+    saxHandler.endElementNs             = NULL;
+    saxHandler.serror                   = NULL;
+
+    // Parse XML file
+    if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Parser and memory cleanups for libxml2
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return md;
+}
Index: /branches/rel4/psLib/src/collections/psMetadataIO.h
===================================================================
--- /branches/rel4/psLib/src/collections/psMetadataIO.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psMetadataIO.h	(revision 3057)
@@ -0,0 +1,85 @@
+/** @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.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-06 20:00:03 $
+*
+*  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.
+ */
+bool psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* 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.
+    psS32 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 psMetadata* : Resulting metadata from read.
+ */
+psMetadata* psMetadataParseConfig(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/** Read XML metadata configuration file.
+ *
+ *  Loads pre-defined XML settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return psMetadata* : Resulting metadata from read.
+ */
+
+psMetadata*  psMetadataParseConfigXml(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/collections/psScalar.c
===================================================================
--- /branches/rel4/psLib/src/collections/psScalar.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psScalar.c	(revision 3057)
@@ -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.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-08 02:03:49 $
+ *
+ *  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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                dataType);
+        psFree(scalar);
+        return NULL;
+    }
+
+    return scalar;
+}
+
+psScalar* psScalarCopy(psScalar *scalar)
+{
+    psElemType dataType;
+    psScalar *newScalar = NULL;
+
+    if (scalar == NULL) {
+        psError(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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                dataType);
+        return NULL;
+    }
+
+    return newScalar;
+}
Index: /branches/rel4/psLib/src/collections/psScalar.h
===================================================================
--- /branches/rel4/psLib/src/collections/psScalar.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psScalar.h	(revision 3057)
@@ -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/rel4/psLib/src/collections/psVector.c
===================================================================
--- /branches/rel4/psLib/src/collections/psVector.c	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psVector.c	(revision 3057)
@@ -0,0 +1,408 @@
+
+/** @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.32 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-09 21:30:43 $
+*
+*  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(psU32 nalloc, psElemType elemType)
+{
+    psVector* psVec = NULL;
+    psS32 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, psU32 nalloc)
+{
+    psS32 elementSize = 0;
+    psElemType elemType;
+
+    if (in == NULL) {
+        psError(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, psU32 n, psElemType type)
+{
+    psS32 byteSize;
+
+    if (in == NULL) {
+        return psVectorAlloc(n, type);
+    }
+
+    if (in->type.dimen !=  PS_DIMEN_VECTOR &&
+            in->type.dimen !=  PS_DIMEN_TRANSV) {
+        psFree(in);
+        psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    psS32 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 (psS32 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); \
+                psError(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);
+            psError(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)
+{
+    psS32 N = 0;
+    psS32 elSize = 0;
+    psPtr inVec = NULL;
+    psPtr outVec = NULL;
+    psElemType inType = 0;
+
+    if (inVector == NULL) {
+        psError(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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                inType);
+    }
+
+    return outVector;
+}
+
+psVector* psVectorSortIndex(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    psS32 N = 0;
+    psVector* tmpVector = NULL;
+    psVector* checkVector = NULL;
+    psElemType inType = 0;
+    psU32* outVec;
+
+    if (inVector == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    inType = inVector->type.type;
+    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);
+
+    checkVector = psVectorAlloc(N,PS_TYPE_U8);
+    for(psS32 k=0; k<N; k++) {
+        checkVector->data.U8[k] = 0;
+    }
+
+    #define SORT_INDICES(TYPE,absfcn,maxError) {                              \
+        ps##TYPE* inVec = inVector->data.TYPE;                                \
+        ps##TYPE* tmpVec = tmpVector->data.TYPE;                              \
+        ps##TYPE  diff;                                                       \
+        for(psS32 i=0; i<N; i++) {                                              \
+            for(psS32 j=0; j<N; j++) {                                          \
+                if(checkVector->data.U8[j] == 0 ) {                                    \
+                    diff = absfcn(tmpVec[i] - inVec[j]);                          \
+                    if(diff < maxError) {                                         \
+                        outVec[i] = j;                                            \
+                        checkVector->data.U8[j] = 1; \
+                        break;                                                    \
+                    }                                                             \
+                } \
+            }                                                                 \
+        }                                                                     \
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        SORT_INDICES(U8,abs,1);
+        break;
+    case PS_TYPE_U16:
+        SORT_INDICES(U16,abs,1);
+        break;
+    case PS_TYPE_U32:
+        SORT_INDICES(U32,abs,1);
+        break;
+    case PS_TYPE_U64:
+        SORT_INDICES(U64,abs,1);
+        break;
+    case PS_TYPE_S8:
+        SORT_INDICES(S8,abs,1);
+        break;
+    case PS_TYPE_S16:
+        SORT_INDICES(S16,abs,1);
+        break;
+    case PS_TYPE_S32:
+        SORT_INDICES(S32,abs,1);
+        break;
+    case PS_TYPE_S64:
+        SORT_INDICES(S64,abs,1);
+        break;
+    case PS_TYPE_F32:
+        SORT_INDICES(F32,fabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_F64:
+        SORT_INDICES(F64,fabs,DBL_EPSILON);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                inType);
+    }
+
+    // Free temp memory
+    psFree(tmpVector);
+    psFree(checkVector);
+
+    return outVector;
+}
Index: /branches/rel4/psLib/src/collections/psVector.h
===================================================================
--- /branches/rel4/psLib/src/collections/psVector.h	(revision 3057)
+++ /branches/rel4/psLib/src/collections/psVector.h	(revision 3057)
@@ -0,0 +1,148 @@
+/** @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.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
+ *
+ *  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.
+    psU32 nalloc;        ///< Total number of elements available.
+    psU32 n;             ///< Number of elements in use.
+
+    union {
+        psBool B;               ///< Boolean data.
+        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(
+    psU32 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.
+    psU32 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.
+
+    psU32 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/rel4/psLib/src/convertType.sh
===================================================================
--- /branches/rel4/psLib/src/convertType.sh	(revision 3057)
+++ /branches/rel4/psLib/src/convertType.sh	(revision 3057)
@@ -0,0 +1,13 @@
+#!/bin/sh
+sed -i -r "s/([[:space:]\(,]|^)unsigned short([[:space:]\)\*,])/\1psU16\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)unsigned int([[:space:]\)\*,])/\1psU32\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)unsigned long([[:space:]\)\*,])/\1psU64\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)short([[:space:]\)\*,])/\1psS16\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)long int([[:space:]\)\*,])/\1psS64\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)long([[:space:]\)\*,])/\1psS64\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)int([[:space:]\)\*,])/\1psS32\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)unsigned char([[:space:]\)\*,])/\1psStr\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)bool([[:space:]\)\*,])/\1psBool\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)void \*/\1psPtr /g" *
+sed -i -r "s/([[:space:]\(,]|^)void\*([[:space:]\)\*,])/\1psPtr\2/g" *
+sed -i -r "s/([[:space:]\(,]|^)psPTR([[:space:]\)\*,])/\1psPtr\2/g" *
Index: /branches/rel4/psLib/src/dataIO/Makefile
===================================================================
--- /branches/rel4/psLib/src/dataIO/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/Makefile	(revision 3057)
@@ -0,0 +1,60 @@
+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 -I../astronomy -DSER7_FILE="\"$(SER7_FILE)\"" -DTAIUTC_FILE="\"$(TAIUTC_FILE)\""
+
+SRC_OBJS = psLookupTable.o \
+	psFits.o
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h)
+
+all: $(TARGET_STATIC)
+
+psFileUtilsErrors.h: psFileUtilsErrors.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 'fileUtils'"
+	$(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/rel4/psLib/src/dataIO/psFileUtilsErrors.dat
===================================================================
--- /branches/rel4/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 3057)
@@ -0,0 +1,57 @@
+#
+#  This file is used to generate psFileUtilsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERROR_TEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+psLookupTable_FILE_NOT_FOUND           Failed to open file %s.
+psLookupTable_PARSE_VALUE              Unable to parse string, %s on line %lld.
+psLookupTable_PARSE_TYPE               Unable to parse type, %s on line %lld.
+psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld
+psLookupTable_INTERPOLATE_HIGH         High index too big, %d.
+psLookupTable_INTERPOLATE_LOW          Low index too small, %d.
+psLookupTable_DIVIDE_BY_ZERO           Divide by zero error during interpolation.
+psLookupTable_INVALID_TYPE             Invalid psLookupType, %d;
+#
+psFits_NULL                            The input psFits object can not NULL.
+psFits_FILENAME_INVALID                Could not open file,'%s'.\nCFITSIO Error: %s
+psFits_FILENAME_NULL                   Specified filename can not be NULL.
+psFits_EXTNAME_NULL                    Specified extension name can not be NULL.
+psFits_EXTNAME_INVALID                 Could not find HDU '%s' in file %s.\nCFITSIO Error: %s
+psFits_EXTNUM_ABS_MOVE_FAILED          Could not move to specified HDU #%d in file %s.\nCFITSIO Error: %s
+psFits_EXTNUM_REL_MOVE_FAILED          Could not move %d HDUs from current position in file %s.\nCFITSIO Error: %s
+psFits_GET_EXTNUM_FAILED               Failed to determine the current HDU number in file %s.\nCFITSIO Error: %s
+psFits_GETNUMHDUS_FAILED               Failed to determine the number of HDUs in file %s.\nCFITSIO Error: %s
+psFits_GETHDUTYPE_FAILED               Failed to determine an HDU type in file %s.\nCFITSIO Error: %s
+psFits_GETNUMKEYS_FAILED               Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s
+psFits_GET_TABLE_SIZE_FAILED           Failed to determine the size of the current HDU table.\nCFITSIO Error: %s
+psFits_FILENAME_CREATE_FAILED          Could not create file,'%s'.\nCFITSIO Error: %s
+psFits_TYPE_UNSUPPORTED                Specified type, %s, is not supported.
+psFits_CREATE_HDU_FAILED               Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s
+psFits_GET_HDU_TYPE_FAILED             Could not determine the HDU type.\nCFITSIO Error: %s
+psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
+psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
+psFits_TABLE_EMPTY                     Can't create a table without any rows.
+psFits_CFITSIO_ERROR                   CFITSIO error: %s
+psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
+psFits_METADATA_ADD_FAILED             Failed to add metadata item, %s.
+psFits_WRITE_FAILED                    Could not write data to file,'%s'.\nCFITSIO Error: %s
+psFits_IMAGE_NULL                      The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
+psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
+psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
+psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.
+psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
+psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
+psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
+psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
+psFits_DATATYPE_UNKNOWN                Could not determine image data type.\nCFITSIO Error: %s
+psFits_IMAGE_DIM_UNKNOWN               Could not determine image dimensions.\nCFITSIO Error: %s
+psFits_IMAGE_DIMENSION_UNSUPPORTED     Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O.
+psFits_IMAGE_SIZE_UNKNOWN              Could not determine image size.\nCFITSIO Error: %s
+psFits_FITS_TYPE_UNSUPPORTED           FITS image type, BITPIX=%d, is not supported.
+psFits_READ_FAILED                     Reading FITS file failed.\nCFITSIO Error: %s
+psFits_IMAGE_UPDATE_TYPE_MISMATCH      Can not update a %s image given a %s image.
+psFits_FITS_Z_SMALL                    Current FITS HDU has %d z-planes, but z-plane %d was specified.
+#
Index: /branches/rel4/psLib/src/dataIO/psFileUtilsErrors.h
===================================================================
--- /branches/rel4/psLib/src/dataIO/psFileUtilsErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psFileUtilsErrors.h	(revision 3057)
@@ -0,0 +1,81 @@
+/** @file  psFileUtilsErrors.h
+ *
+ *  @brief Contains the error text for the fileUtils functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FILEUTIL_ERRORS_H
+#define PS_FILEUTIL_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_psLookupTable_FILE_NOT_FOUND "Failed to open file %s."
+#define PS_ERRORTEXT_psLookupTable_PARSE_VALUE "Unable to parse string, %s on line %lld."
+#define PS_ERRORTEXT_psLookupTable_PARSE_TYPE "Unable to parse type, %s on line %lld."
+#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld"
+#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH "High index too big, %d."
+#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW "Low index too small, %d."
+#define PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO "Divide by zero error during interpolation."
+#define PS_ERRORTEXT_psLookupTable_INVALID_TYPE "Invalid psLookupType, %d;"
+#define PS_ERRORTEXT_psFits_NULL "The input psFits object can not NULL."
+#define PS_ERRORTEXT_psFits_FILENAME_INVALID "Could not open file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FILENAME_NULL "Specified filename can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_NULL "Specified extension name can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_INVALID "Could not find HDU '%s' in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_EXTNUM_ABS_MOVE_FAILED "Could not move to specified HDU #%d in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_EXTNUM_REL_MOVE_FAILED "Could not move %d HDUs from current position in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_EXTNUM_FAILED "Failed to determine the current HDU number in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED "Failed to determine the number of HDUs in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED "Failed to determine an HDU type in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED "Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED "Failed to determine the size of the current HDU table.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED "Could not create file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED "Specified type, %s, is not supported."
+#define PS_ERRORTEXT_psFits_CREATE_HDU_FAILED "Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED "Could not determine the HDU type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
+#define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
+#define PS_ERRORTEXT_psFits_TABLE_EMPTY "Can't create a table without any rows."
+#define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
+#define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
+#define PS_ERRORTEXT_psFits_METADATA_ADD_FAILED "Failed to add metadata item, %s."
+#define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write data to file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_NULL "The input psImage was NULL.  Need a non-NULL psImage for operation to be performed."
+#define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
+#define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
+#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows."
+#define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN "Could not determine image data type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN "Could not determine image dimensions.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED "Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O."
+#define PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN "Could not determine image size.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, is not supported."
+#define PS_ERRORTEXT_psFits_READ_FAILED "Reading FITS file failed.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH "Can not update a %s image given a %s image."
+#define PS_ERRORTEXT_psFits_FITS_Z_SMALL "Current FITS HDU has %d z-planes, but z-plane %d was specified."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/dataIO/psFits.c
===================================================================
--- /branches/rel4/psLib/src/dataIO/psFits.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psFits.c	(revision 3057)
@@ -0,0 +1,1622 @@
+/** @file  psFits.c
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 20:01:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+
+#include "psFits.h"
+#include "string.h"
+#include "psError.h"
+#include "psFileUtilsErrors.h"
+#include "psImageExtraction.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psLogMsg.h"
+#include "psTrace.h"
+
+#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
+
+static char* standardFitsKeys[] = {
+                                      "SIMPLE",
+                                      "BITPIX",
+                                      "NAXIS",
+                                      "NAXIS1",
+                                      "NAXIS2",
+                                      "NAXIS3",
+                                      "EXTEND",
+                                      "COMMENT",
+                                      "EXTNAME",
+                                      "HDUNAME",
+                                      "XTENSION",
+                                      "TFIELDS",
+                                      NULL
+                                  };
+
+static psElemType convertFitsToPsType(int datatype)
+{
+    switch (datatype) {
+    case TBYTE:
+        return PS_TYPE_U8;
+    case TSBYTE:
+        return PS_TYPE_S8;
+    case TSHORT:
+        return PS_TYPE_S16;
+    case TUSHORT:
+        return PS_TYPE_U16;
+    case TLONG:
+        if (sizeof(long) == 8) {
+            return PS_TYPE_S64;
+        }
+        // no break
+    case TINT:
+        return PS_TYPE_S32;
+    case TULONG:
+        if (sizeof(unsigned long) == 8) {
+            return PS_TYPE_U64;
+        }
+        // no break
+    case TUINT:
+        return PS_TYPE_U32;
+    case TLONGLONG:
+        return PS_TYPE_S64;
+    case TFLOAT:
+        return PS_TYPE_F32;
+    case TDOUBLE:
+        return PS_TYPE_F64;
+    case TCOMPLEX:
+        return PS_TYPE_C32;
+    case TDBLCOMPLEX:
+        return PS_TYPE_C64;
+    default:
+        return PS_TYPE_PTR;
+    }
+}
+
+
+static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
+{
+
+    int bitpix;
+    int datatype;
+    double bzero = 0.0;
+
+    switch (type) {
+
+    case PS_TYPE_U8:
+        bitpix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+
+    case PS_TYPE_S8:
+        bitpix = BYTE_IMG;
+        bzero = INT8_MIN;
+        datatype = TSBYTE;
+        break;
+
+    case PS_TYPE_U16:
+        bitpix = SHORT_IMG;
+        bzero = -1.0 * INT16_MIN;
+        datatype = TUSHORT;
+        break;
+
+    case PS_TYPE_S16:
+        bitpix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+
+    case PS_TYPE_U32:
+        bitpix = LONG_IMG;
+        bzero = -1.0 * 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,type);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED,
+                    typeStr);
+            return false;
+        }
+    }
+
+    // pass the requested parameters  (NULL parameters are not set, of course).
+    if (bitPix != NULL) {
+        *bitPix = bitpix;
+    }
+
+    if (dataType != NULL) {
+        *dataType = datatype;
+    }
+
+    if (bZero != NULL) {
+        *bZero = bzero;
+    }
+
+    return true;
+}
+
+static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
+{
+    switch (type) {
+    case PS_TYPE_BOOL:
+        *fitsType = psStringCopy("1L");
+        break;
+    case PS_TYPE_S32:
+        *fitsType = psStringCopy("1J");
+        break;
+    case PS_TYPE_F32:
+        *fitsType = psStringCopy("1E");
+        break;
+    case PS_TYPE_F64:
+        *fitsType = psStringCopy("1D");
+        break;
+        // XXX: Handle other types, e.g., Vectors, etc.
+    default:
+        return false;
+    }
+
+    return true;
+}
+
+static bool isHDUEmpty(psFits* fits)
+{
+    /* check for keys - no keys means this is really an empty HDU */
+    int keysexist = -1;
+    int morekeys;
+    int status = 0;
+
+    fits_get_hdrspace(fits->p_fd, &keysexist, &morekeys, &status);
+
+    // if no keys exist and not primary HDU, this really is an empty HDU
+    if (keysexist == 0) {
+        return true;
+    }
+
+    return false;
+
+}
+
+static void fitsFree(psFits* fits)
+{
+    int status = 0;
+
+    if (fits != NULL) {
+        (void)fits_close_file(fits->p_fd, &status);
+        psFree((void*)fits->filename);
+    }
+}
+
+psFits* psFitsAlloc(const char* name)
+{
+    int status = 0;
+    fitsfile *fptr = NULL;      /* Pointer to the FITS file */
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_FILENAME_NULL);
+        return NULL;
+    }
+
+    /* Open/Create the FITS file */
+    if (access(name, F_OK) == 0) {     // file exists
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psFits_FILENAME_INVALID,
+                    name, fitsErr);
+            return NULL;
+        }
+    } else {  // file does not exist, so create.
+        (void)fits_create_file(&fptr, name, &status);
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED,
+                    name, fitsErr);
+            return NULL;
+        }
+    }
+
+    psFits* fits = psAlloc(sizeof(psFits));
+    fits->filename = psAlloc(strlen(name)+1);
+    fits->p_fd = fptr;
+    strcpy((char*)fits->filename,name);
+    p_psMemSetDeallocator(fits,(psFreeFcn)fitsFree);
+
+    return fits;
+}
+
+bool psFitsMoveExtName(psFits* fits,
+                       const char* extname)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+
+    if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_EXTNAME_INVALID,
+                extname, fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsMoveExtNum(psFits* fits,
+                      int extnum,
+                      bool relative)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    int status = 0;
+    int hdutype = 0;
+
+    if (relative) {
+        fits_movrel_hdu(fits->p_fd, extnum, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_REL_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    } else {
+        fits_movabs_hdu(fits->p_fd, extnum+1, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_ABS_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+int psFitsGetExtNum(psFits* fits)
+{
+    int hdunum;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+
+    return fits_get_hdu_num(fits->p_fd,&hdunum) - 1;
+}
+
+char* psFitsGetExtName(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    int status = 0;
+    char name[MAX_STRING_LENGTH];
+
+    if (fits_read_key_str(fits->p_fd, "EXTNAME", name, NULL, &status) != 0) {
+        status = 0;
+        if (fits_read_key_str(fits->p_fd, "HDUNAME", name, NULL, &status) != 0) {
+            int num = psFitsGetExtNum(fits);
+            snprintf(name, MAX_STRING_LENGTH, "EXT-%3d",num);
+        }
+    }
+    return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+int psFitsGetSize(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return 0;
+    }
+
+    int num = 0;
+    int status = 0;
+
+    if (fits_get_num_hdus(fits->p_fd, &num, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED,
+                fits->filename, fitsErr);
+        return 0;
+    }
+
+    return num;
+}
+
+psFitsType psFitsGetExtType(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    int status = 0;
+    int hdutype = PS_FITS_TYPE_NONE;
+
+    if (fits_get_hdu_type(fits->p_fd, &hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED,
+                fits->filename, fitsErr);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    if (hdutype == PS_FITS_TYPE_IMAGE &&
+            psFitsGetExtNum(fits) > 0 &&
+            isHDUEmpty(fits)) {
+        return PS_FITS_TYPE_ANY;
+    }
+
+    return hdutype;
+}
+
+psMetadata* psFitsReadHeader(psMetadata* out,
+                             const psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psMetadataAlloc();
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psMetadata container.");
+            return NULL;
+        }
+    }
+
+    // Get number of key names
+    int numKeys = 0;
+    int keyNum = 0;
+    int status = 0;
+    fits_get_hdrpos(fits->p_fd, &numKeys, &keyNum, &status);
+
+    // Get each key name. Keywords start at one.
+    char keyType;
+    char keyName[MAX_STRING_LENGTH];
+    char keyValue[MAX_STRING_LENGTH];
+    char keyComment[MAX_STRING_LENGTH];
+    psBool tempBool;
+    psBool success;
+    psBool stdKey;
+    for (int i = 1; i <= numKeys; i++) {
+
+        fits_read_keyn(fits->p_fd, i, keyName, keyValue, keyComment, &status);
+
+        stdKey = false;
+
+        int stdKeyIdx = 0;
+        while (standardFitsKeys[stdKeyIdx] != NULL && ! stdKey) {
+            if (strcmp(keyName,standardFitsKeys[stdKeyIdx++]) == 0) {
+                stdKey = true;
+            }
+        }
+
+        if (keyValue[0] != 0) { // blank values are not handled by fits_get_keytype
+            fits_get_keytype(keyValue, &keyType, &status);
+        } else {
+            keyType = 'C';
+        }
+        if (status != 0) {
+            break;
+        }
+
+        if (! stdKey) {
+            switch (keyType) {
+            case 'X': // bit
+            case 'I': // short int.
+            case 'J': // int.
+            case 'B': // byte
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_S32,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atoi(keyValue));
+                break;
+            case 'U': // unsigned int. may not fit in a psS32
+            case 'K': // long int. can't all fit in a psS32
+            case 'F':
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_F64,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atof(keyValue));
+                break;
+            case 'C':
+                // remove the single-quotes at front/end
+                if (keyValue[0] == '\'' && keyValue[strlen(keyValue)-1] == '\'') {
+                    keyValue[strlen(keyValue)-1] = '\0';
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue+1);
+                } else {
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue);
+                }
+                break;
+            case 'L':
+                tempBool = (keyValue[0] == 'T') ? 1 : 0;
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_BOOL,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        tempBool);
+                break;
+            default:
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psFits_METATYPE_INVALID,
+                        keyType);
+                return out;
+            }
+
+            if (!success) {
+                psError(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                        keyName);
+                return out;
+            }
+        }
+
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                fitsErr);
+        return false;
+    }
+
+    return out;
+}
+
+psHash* psFitsReadHeaderSet(psHash* out,
+                            psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psHashAlloc(10);
+        // XXX: what is the appropriate number of buckets? Got 10 from psMetadataAlloc.
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psHash container.");
+            return NULL;
+        }
+    }
+
+    int size = psFitsGetSize(fits);
+
+    int origPosition = psFitsGetExtNum(fits);
+
+    for (int lcv=0; lcv < size; lcv++) {
+        psFitsMoveExtNum(fits, lcv, false);
+
+        char* name = NULL;
+        if (lcv == 0) {
+            name = psStringCopy("PHU");
+        } else {
+            name = psFitsGetExtName(fits);
+        }
+
+        psMetadata* header = psFitsReadHeader(NULL, fits);
+        if (name != NULL && header != NULL) {
+            psHashAdd(out, name, header);
+        } else { // XXX: is this a warning or error?
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "Failed to read HDU#%d header data.",
+                     lcv);
+        }
+
+        psFree(name);
+        psFree(header);
+    }
+
+    // reposition to the original position
+    psFitsMoveExtNum(fits, origPosition, false);
+
+    return out;
+}
+
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 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 */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    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:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        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:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    if (output == NULL)
+    {
+        psError(PS_ERR_UNKNOWN, false,
+                "Failed to allocate a properly sized image.");
+        return false;
+    }
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
+bool psFitsWriteImage(psFits* fits,
+                      const psMetadata* header,
+                      const psImage* input,
+                      int numZPlanes,
+                      char* extname)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    int status = 0;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    int naxis = 3;
+    long naxes[3];
+
+    naxes[0] = numCols;
+    naxes[1] = numRows;
+    naxes[2] = numZPlanes;
+
+    if (numZPlanes < 2) {
+        naxis = 2;
+    }
+
+    fits_create_img(fits->p_fd, bitPix, naxis, naxes, &status);
+
+    if (extname != NULL) {
+        fits_update_key_str(fits->p_fd, "EXTNAME", (char*)extname, NULL, &status);
+    }
+
+    if (bZero != 0) {        // set the bscale/bzero
+        fits_write_key_dbl(fits->p_fd, "BZERO", bZero, 12, "Pixel Value Offset", &status);
+        fits_write_key_dbl(fits->p_fd, "BSCALE", 1.0, 12, "Pixel Value Scale", &status);
+        fits_set_bscale(fits->p_fd, 1.0, bZero, &status);
+    }
+
+    // write the header, if any.
+    if (header != NULL) {
+        psFitsWriteHeader(header, fits);
+    }
+
+    if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
+        fits_write_img(fits->p_fd,
+                       dataType,              // datatype
+                       1,                     // writing to the first z-plane
+                       numCols*numRows,       // number of elements to write, i.e., the whole image
+                       input->data.V[0],      // the data
+                       &status);
+    } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
+        for (int row = 0; row < numRows; row++) {
+            fits_write_img(fits->p_fd,
+                           dataType,          // datatype
+                           firstPixel,
+                           numCols,           // number of elements to write, i.e., one row's worth
+                           input->data.V[row],// the raw row data
+                           &status);
+            firstPixel += numCols;  // move to next row
+        }
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+
+}
+
+bool psFitsUpdateImage(psFits* fits,
+                       const psImage* input,
+                       psRegion region,
+                       int z)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    // check to see if we are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    //check to see if the HDU has the same datatype
+    int fileBitpix;
+    int naxis;
+    long nAxes[3];
+    nAxes[2] = 1;
+    fits_get_img_param(fits->p_fd, 3, &fileBitpix, &naxis, nAxes, &status);
+
+    //check to see if the HDU has the same datatype
+    if (bitPix != fileBitpix) {
+        char* fitsTypeStr;
+        char* imageTypeStr;
+        PS_TYPE_NAME(fitsTypeStr,fileBitpix);
+        PS_TYPE_NAME(imageTypeStr,input->type.type);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH,
+                fitsTypeStr, imageTypeStr);
+        return false;
+    }
+
+    //check if the HDU has the z-plane requested
+    if (z >= nAxes[2]) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_FITS_Z_SMALL,
+                nAxes[2],z);
+        return false;
+    }
+
+    // determine the region in the FITS file domain
+    long firstPixel[3];
+    long lastPixel[3];
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0) {
+        lastPixel[0] = region.x1;
+    } else {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0) {
+        lastPixel[1] = region.y1;
+    } else {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    if (firstPixel[0] < 1 || firstPixel[0] > nAxes[0] ||
+            firstPixel[1] < 1 || firstPixel[1] > nAxes[1] ||
+            lastPixel[0] < 1 || lastPixel[0] > nAxes[0] ||
+            lastPixel[1] < 1 || lastPixel[1] > nAxes[1]) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified region [%d:%d,%d:%d], is not valid given the %dx%d FITS image.",
+                region.y0,region.y1-1,region.x0,region.x1-1);
+        return false;
+
+    }
+
+    int dx = lastPixel[0] - firstPixel[0];
+    int dy = lastPixel[1] - firstPixel[1];
+    if (dx > numCols ||
+            dy > numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "The region [%d:%d,%d:%d], is not valid given the input %dx%d image.",
+                firstPixel[1]-1,lastPixel[1]-1,
+                firstPixel[0]-1,lastPixel[0]-1,
+                numCols, numRows);
+        return false;
+    }
+
+    psImage* subset;
+    if (dx != numCols || dy != numRows) {
+        // the input image needs to be subsetted
+        subset = psImageSubset((psImage*)input,0,0,dx+1,dy+1);
+    } else {
+        subset = psMemIncrRefCounter((psImage*)input);
+    }
+
+    fits_write_subset(fits->p_fd, dataType, firstPixel, lastPixel, subset->data.V[0], &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsWriteHeader(const psMetadata* header,
+                       psFits* fits)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (header == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_METADATA_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    //transverse the metadata list and add each key.
+
+    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
+    psMetadataItem* item;
+    while ( (item=psListGetNext(iter)) != NULL ) {
+        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
+            switch (item->pType) {
+            case PS_TYPE_BOOL: {
+                    int value = item->data.B;
+                    fits_update_key(fits->p_fd,
+                                    TLOGICAL,
+                                    item->name,
+                                    &value,
+                                    item->comment,
+                                    &status);
+                    break;
+                }
+            case PS_TYPE_S32:
+                fits_update_key(fits->p_fd,
+                                TINT,
+                                item->name,
+                                &item->data.S32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F32:
+                fits_update_key(fits->p_fd,
+                                TFLOAT,
+                                item->name,
+                                &item->data.F32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F64:
+                fits_update_key(fits->p_fd,
+                                TDOUBLE,
+                                item->name,
+                                &item->data.F64,
+                                item->comment,
+                                &status);
+                break;
+            default:
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
+                        item->pType);
+                break;
+            }
+        } else if (item->type == PS_META_STR) {
+            fits_update_key(fits->p_fd,
+                            TSTRING,
+                            item->name,
+                            item->data.V,
+                            item->comment,
+                            &status);
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_WRITE_FAILED,
+                    fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psMetadata* psFitsReadTableRow(psFits* fits,
+                               int row)
+{
+    long numRows;
+    int numCols;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    fits_get_num_cols(fits->p_fd, &numCols, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    // the row parameter in the proper range?
+    if (row < 0 || row >= numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psFits_ROW_INVALID,
+                row,numRows);
+        return NULL;
+    }
+
+    psMetadata* data = psMetadataAlloc();
+
+    int typecode;
+    long repeat;
+    long width;
+    char name[60];
+    for (int col = 1; col <= numCols; col++) {
+        // get the column name
+        if (hdutype == BINARY_TBL) {
+            fits_get_bcolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        } else {
+            fits_get_acolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        }
+
+        // get the column type
+        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
+
+        if (status == 0) {
+
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
+        case FITSTYPE: { \
+                NATIVETYPE value = 0; \
+                int anynul = 0; \
+                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
+                              1, 1, NULL, &value, &anynul, &status); \
+                psMetadataAdd(data,PS_LIST_TAIL, name, \
+                              PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                              "", (ps##TYPE)value); \
+                break; \
+            }
+
+            switch (typecode) {
+            case TBYTE:
+            case TSHORT:
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
+            default:
+                psTrace("psFits.psFitsReadTableRow", 2,
+                        "Column %d or row %d was of a non primitive type, %d",
+                        col, row, typecode);
+            }
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
+                    col,row,fitsErr);
+            psFree(data);
+            return NULL;
+        }
+
+    }
+
+    return data;
+}
+
+psArray* psFitsReadTableColumn(psFits* fits,
+                               const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    psArray* result = psArrayAlloc(numRows);
+
+    fits_read_col_str(fits->p_fd,
+                      colnum,
+                      1, // firstrow
+                      1, // firestelem
+                      numRows,
+                      "", // nulstr
+                      (char**)result->data,
+                      NULL,
+                      &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+psVector* psFitsReadTableColumnNum(psFits* fits,
+                                   const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    // get the column datatype.
+    int typecode;
+    long repeat;
+    long width;
+    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_COLTYPE,
+                fitsErr);
+        return NULL;
+    }
+
+    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
+
+    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
+                  1 /* firstelem */, numRows, NULL, result->data.V,
+                  NULL, &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+
+psArray* psFitsReadTable(psFits* fits)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    psArray* table = psArrayAlloc(numRows);
+
+    for (int row = 0; row < numRows; row++) {
+        table->data[row] = psFitsReadTableRow(fits,row);
+    }
+
+    return table;
+}
+
+bool psFitsWriteTable(psFits* fits,
+                      psMetadata* header,
+                      psArray* table,
+                      char* extname)
+{
+    int status = 0;
+    psMetadataItem* item;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
+
+    // find all the columns needed
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
+    columns->n=0;
+
+    // find the unique items in the array of metadata 'rows'
+    for (int row=0; row < rows; row++) {
+        psMetadata* rowMeta = table->data[row];
+        if (rowMeta != NULL) {
+            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
+                                   PS_LIST_HEAD);
+            while ( (item=psListGetNext(iter)) != NULL) {
+                if (item->type == PS_META_PRIMITIVE) {
+                    bool found = false;
+                    for (int n=0; n < columns->n && ! found; n++) {
+                        if (strcmp(item->name,
+                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
+                            found = true;
+                        }
+                    }
+                    if (! found) {
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
+                    }
+                }
+            }
+            psFree(iter);
+        }
+    }
+
+    if (columns->n == 0) { // no table columns found
+        // XXX: Error?
+        return false;
+    }
+
+    //create list of column names and types.
+    psArray* columnNames = psArrayAlloc(columns->n);
+    psArray* columnTypes = psArrayAlloc(columns->n);
+    for (int n=0; n < columns->n; n++) {
+        char* fitsType;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
+        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
+                                          &fitsType)) {
+            // XXX: error message
+            return false;
+        }
+        columnTypes->data[n] = fitsType;
+    }
+
+    fits_create_tbl(fits->p_fd,
+                    BINARY_TBL,
+                    table->n, // number of rows in table
+                    columns->n, // number of columns in table
+                    (char**)columnNames->data, // names of the columns
+                    (char**)columnTypes->data, // format of the columns
+                    NULL, // physical unit of columns
+                    extname, // extension name
+                    &status);
+
+    psFree(columnNames);
+    psFree(columnTypes);
+
+    // fill in the table elements with data
+    for (int n = 0; n < columns->n; n++) {
+        int row;
+        item = columns->data[n];
+
+        if (item->type == PS_META_PRIMITIVE) {
+            psVector* col = psVectorAlloc(table->n, item->pType);
+            switch (item->pType) {
+            case PS_TYPE_S32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_int(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S32,
+                                   &status);
+                break;
+            case PS_TYPE_F32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_flt(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F32,
+                                   &status);
+                break;
+            case PS_TYPE_F64:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_dbl(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F64,
+                                   &status);
+                break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
+            default:
+                // XXX: error message
+                break;
+            }
+            psFree(col);
+        } else if (item->type == PS_META_STR) {
+            psArray* col = psArrayAlloc(table->n);
+            for (row = 0; row < table->n; row++) {
+                col->data[row] = item->data.V;
+            }
+            fits_write_col_str(fits->p_fd,
+                               n, // column number
+                               1, // firstrow
+                               1, // firstelem
+                               table->n, // nelements
+                               (char**)col->data,
+                               &status);
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
+
+    return true;
+}
Index: /branches/rel4/psLib/src/dataIO/psFits.h
===================================================================
--- /branches/rel4/psLib/src/dataIO/psFits.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psFits.h	(revision 3057)
@@ -0,0 +1,266 @@
+/** @file  psFits.h
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FITS_H
+#define PS_FITS_H
+
+#include<fitsio.h>
+
+#include "psType.h"
+#include "psArray.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psHash.h"
+#include "psImage.h"
+
+/// @addtogroup FileIO
+/// @{
+
+typedef enum {
+    PS_FITS_TYPE_NONE = -1,
+    PS_FITS_TYPE_IMAGE = IMAGE_HDU,
+    PS_FITS_TYPE_BINARY_TABLE = BINARY_TBL,
+    PS_FITS_TYPE_ASCII_TABLE = ASCII_TBL,
+    PS_FITS_TYPE_ANY = ANY_HDU
+} psFitsType;
+
+/** FITS file object.
+ *
+ *  This object should be considered opaque to the user; no item in this
+ *  struct should be accessed directly.
+ *
+ */
+typedef struct
+{
+    fitsfile* p_fd;                    ///< the CFITSIO fits files handle.
+    const char* filename;              ///< the filename of the fits file
+}
+psFits;
+
+/** Opens a FITS file and allocates the associated psFits object.
+ *
+ *  @return psFits*    new psFits object for the FITS files specified or
+ *                     NULL if the open of the FITS file failed
+ */
+psFits* psFitsAlloc(
+    const char* name                   ///< the FITS file name
+);
+
+/** Moves the FITS HDU to the specified extension name.
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtName(
+    psFits* fits,                      ///< the psFits object to move
+    const char* extname                ///< the extension name
+);
+
+/** Moves the FITS HDU to the specified extension number
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtNum(
+    psFits* fits,                      ///< the psFits object to move
+    int extnum,                        ///< the extension number to move to (zero is primary HDU)
+    bool relative                      ///< if true, extnum is a relative number to the current position
+);
+
+/** Get the current extension number, where 0 is the primary HDU.
+ *
+ *  @return int        Current HDU number of the psFits file or < 0 if an error
+ *                     occurred.
+ */
+int psFitsGetExtNum(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the current extension name.
+ *
+ *  @return int        Current HDU name of the psFits file or NULL if an
+ *                     error occurred.
+ */
+char* psFitsGetExtName(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
+/** Get the total number of HDUs in the FITS file.
+ *
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
+ *                     error occurred.
+ */
+int psFitsGetSize(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the extension type of the current HDU.
+ *
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
+ *                     the type could not be determined.
+ */
+psFitsType psFitsGetExtType(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads the header of the current HDU.
+ *
+ *  @return psMetadata*   the header data
+ */
+psMetadata* psFitsReadHeader(
+    psMetadata* out,
+    ///< The psMetadata to add the header data.  If null, a new psMetadata is created.
+
+    const psFits* fits                 ///< the psFits object
+);
+
+/** Reads the header of all HDUs.  The current HDU is not changed.
+ *
+ *  @return psHash*      the header data
+ */
+psHash* psFitsReadHeaderSet(
+    psHash* out,
+    ///< The psHash to add the header data via psMetadata items.  If null, a
+    ///< new psHash is created.  The keys of the psHash are the extension names
+    ///< of the cooresponding HDUs.
+
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes the values of the metadata to the current HDU header.
+ *
+ *  @return bool        if TRUE, the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteHeader(
+    const psMetadata* header,          ///< the psMetadata data in which to write
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads an image, given the desired region and z-plane.
+ *
+ *  @return psImage*     the read image or NULL if there was an error.
+ */
+psImage* psFitsReadImage(
+    psImage* out,                      ///< a psImage to recycle.
+    psFits* fits,                      ///< the psFits object
+    psRegion region,                   ///< the region in the FITS image to read
+    int z                              ///< the z-plane in the FITS image cube to read
+);
+
+/** Writes an image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteImage(
+    psFits* fits,                      ///< the psFits object
+    const psMetadata* header,          ///< header items for the new HDU.  Can be NULL.
+    const psImage* input,              ///< the image to output
+    int depth,                         ///< the number of z-planes of the FITS image data cube
+    char* extname                      ///< extension name
+);
+
+/** Updates the FITS file image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsUpdateImage(
+    psFits* fits,                      ///< the psFits object
+    const psImage* input,              ///< the image to output
+    psRegion region,                   ///< the region in the FITS image to write
+    int z                              ///< the z-planes of the FITS image data cube to write
+);
+
+/** Reads a table row.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psMetadata*    The table row's data.  The keys are the column names.
+ */
+psMetadata* psFitsReadTableRow(
+    psFits* fits,                      ///< the psFits object
+    int row                            ///< row number to read
+);
+
+/** Reads a table column.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*    Array of data items for the specified column or NULL
+ *                      if an error occurred.
+ */
+psArray* psFitsReadTableColumn(
+    psFits* fits,
+    const char* colname
+);
+
+/** Reads a table column of numbers.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psVector*    Vector of data for the specified column or NULL
+ *                       if an error occurred.
+ */
+psVector* psFitsReadTableColumnNum(
+    psFits* fits,                      ///< the psFits object
+    const char* colname                ///< the column name
+);
+
+
+/** Reads a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*     Array of psMetadata items, which contains the output
+ *                       data items of each row.
+ *
+ *  @see psFitsReadTableRow
+ */
+psArray* psFitsReadTable(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsReadTableRow
+ */
+bool psFitsWriteTable(
+    psFits* fits,                      ///< the psFits object
+    psMetadata* header,                ///< header items for the new HDU.  Can be NULL.
+    psArray* table,
+    ///< Array of psMetadata items, which contains the output data items of each row.
+    char* extname                      ///< extension name
+);
+
+/** Updates a FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsWriteTable
+ */
+bool psFitsUpdateTable(
+    psFits* fits,                      ///< the psFits object
+    psArray* table
+    ///< Array of psMetadata items, which contains the output data items of each row.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/dataIO/psLookupTable.c
===================================================================
--- /branches/rel4/psLib/src/dataIO/psLookupTable.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psLookupTable.c	(revision 3057)
@@ -0,0 +1,670 @@
+/** @file  psLookupTable.c
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-16 18:53:02 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef DARWIN
+#undef __STRICT_ANSI__
+#endif
+#include <stdlib.h>
+#ifdef DARWIN
+#define __STRICT_ANSI__
+#endif
+#include <math.h>
+
+#include "psMemory.h"
+#include "psString.h"
+#include "psError.h"
+#include "psLookupTable.h"
+#include "psFileUtilsErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static bool ignoreLine(char *inString);
+static char *cleanString(char *inString, int sLen);
+static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
+static psU8 parseU8(char *inString, psParseErrorType *status);
+static psS8 parseS8(char *inString, psParseErrorType *status);
+static psU16 parseU16(char *inString, psParseErrorType *status);
+static psS16 parseS16(char *inString, psParseErrorType *status);
+static psU32 parseU32(char *inString, psParseErrorType *status);
+static psS32 parseS32(char *inString, psParseErrorType *status);
+static psU64 parseU64(char *inString, psParseErrorType *status);
+static psS64 parseS64(char *inString, psParseErrorType *status);
+static psF32 parseF32(char *inString, psParseErrorType *status);
+static psF64 parseF64(char *inString, psParseErrorType *status);
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);
+static void lookupTableFree(psLookupTable* table);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+static 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. */
+static 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;
+}
+
+
+/** 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. */
+static char* getToken(char **inString, char *delimiter, psParseErrorType *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 = PS_PARSE_ERROR_GENERAL;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a psU8. The input string must be cleaned and null terminated. */
+static psU8 parseU8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU8 value = 0.0;
+
+
+    value = (psU8)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS8. The input string must be cleaned and null terminated. */
+static psS8 parseS8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS8 value = 0.0;
+
+
+    value = (psS8)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU16. The input string must be cleaned and null terminated. */
+static psU16 parseU16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU16 value = 0.0;
+
+
+    value = (psU16)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS16. The input string must be cleaned and null terminated. */
+static psS16 parseS16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS16 value = 0.0;
+
+
+    value = (psS16)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU32. The input string must be cleaned and null terminated. */
+static psU32 parseU32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU32 value = 0.0;
+
+
+    value = (psU32)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS32. The input string must be cleaned and null terminated. */
+static psS32 parseS32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS32 value = 0.0;
+
+
+    value = (psS32)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU64. The input string must be cleaned and null terminated. */
+static psU64 parseU64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU64 value = 0.0;
+
+
+    value = (psU64)strtoull(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS64. The input string must be cleaned and null terminated. */
+static psS64 parseS64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS64 value = 0.0;
+
+
+    value = (psS64)strtoll(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF32. The input string must be cleaned and null terminated. */
+static psF32 parseF32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF32 value = 0.0;
+
+
+    value = (psF32)strtof(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF64. The input string must be cleaned and null terminated. */
+static psF64 parseF64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF64 value = 0.0;
+
+
+    value = (psF64)strtod(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status)
+{
+    psElemType type;
+
+
+    if(vec == NULL) {
+        *status = 1;
+        return;
+    }
+
+    type = vec->type.type;
+
+    switch(type) {
+    case PS_TYPE_U8:
+        vec->data.U8[index] = parseU8(strValue, status);
+        break;
+    case PS_TYPE_S8:
+        vec->data.S8[index] = parseS8(strValue, status);
+        break;
+    case PS_TYPE_U16:
+        vec->data.U16[index] = parseU16(strValue, status);
+        break;
+    case PS_TYPE_S16:
+        vec->data.S16[index] = parseS16(strValue, status);
+        break;
+    case PS_TYPE_U32:
+        vec->data.U32[index] = parseU32(strValue, status);
+        break;
+    case PS_TYPE_S32:
+        vec->data.S32[index] = parseS32(strValue, status);
+        break;
+    case PS_TYPE_U64:
+        vec->data.U64[index] = parseU64(strValue, status);
+        break;
+    case PS_TYPE_S64:
+        vec->data.S64[index] = parseS64(strValue, status);
+        break;
+    case PS_TYPE_F32:
+        vec->data.F32[index] = parseF32(strValue, status);
+        break;
+    case PS_TYPE_F64:
+        vec->data.F64[index] = parseF64(strValue, status);
+        break;
+    default:
+        *status = PS_PARSE_ERROR_TYPE;
+    }
+
+    return;
+}
+
+static psParseErrorType printError(psU64 lineCount, char* badText, psParseErrorType status)
+{
+    switch(status) {
+    case PS_PARSE_ERROR_VALUE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_VALUE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_TYPE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_TYPE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_GENERAL:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_GENERAL, badText, lineCount);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INVALID_TYPE, badText, lineCount);
+    }
+
+    return PS_LOOKUP_SUCCESS;
+}
+
+static void lookupTableFree(psLookupTable* table)
+{
+    if (table == NULL) {
+        return;
+    }
+
+    psFree(table->values);
+    psFree(table->index);
+    psFree((char*)table->fileName);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psLookupTable* psLookupTableAlloc(const char *fileName, psF64 validFrom, psF64 validTo)
+{
+    psLookupTable *outTable = NULL;
+
+
+    // Can't read table if you don't know its name
+    PS_PTR_CHECK_NULL(fileName,NULL);
+
+    // Allocate lookup table
+    outTable = (psLookupTable*)psAlloc(sizeof(psLookupTable));
+
+    // Set deallocator
+    p_psMemSetDeallocator(outTable, (psFreeFcn)lookupTableFree);
+
+    // Allocate and set metadata item comment
+    outTable->fileName = psStringCopy(fileName);
+
+    // Number of table rows and columns. Automatically resized by table read.
+    outTable->numRows = 0;
+    outTable->numCols = 0;
+
+    // Valid ranges. Automatically set by table read if both zero.
+    outTable->validFrom = validFrom;
+    outTable->validTo = validTo;
+
+    // Vector of independent index values. Filled by table read.
+    outTable->index = NULL;
+
+    // Array of dependent table values corresponding to index values. Filled by table read.
+    outTable->values = NULL;
+
+    return outTable;
+}
+
+psLookupTable* psLookupTableRead(psLookupTable *table)
+{
+    bool typeLine = true;
+    char *line = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *linePtr = NULL;
+    psParseErrorType status = PS_PARSE_SUCCESS;
+    psU64 lineCount = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psU64 failedLines = 0;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(table->fileName,NULL);
+    if((fp=fopen(table->fileName, "r")) == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_FILE_NOT_FOUND, table->fileName);
+        return table;
+    }
+
+    indexVec = table->index;
+    table->values = psArrayAlloc(1);
+    values = table->values;
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // Loop through file to get numRows, numCols, and column data types
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            if(typeLine == true) {
+
+                // Determine column types from first line in data file after comments
+                while((strType=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+                    typeLine = false;
+                    if(!strncmp(strType, "psU8", 4)) {
+                        elemType = PS_TYPE_U8;
+                    } else if(!strncmp(strType, "psS8", 4)) {
+                        elemType = PS_TYPE_S8;
+                    } else if(!strncmp(strType, "psU16", 5)) {
+                        elemType = PS_TYPE_U16;
+                    } else if(!strncmp(strType, "psS16", 5)) {
+                        elemType = PS_TYPE_S16;
+                    } else if(!strncmp(strType, "psU32", 5)) {
+                        elemType = PS_TYPE_U32;
+                    } else if(!strncmp(strType, "psS32", 5)) {
+                        elemType = PS_TYPE_S32;
+                    } else if(!strncmp(strType, "psU64", 5)) {
+                        elemType = PS_TYPE_U64;
+                    } else if(!strncmp(strType, "psS64", 5)) {
+                        elemType = PS_TYPE_S64;
+                    } else if(!strncmp(strType, "psF32", 5)) {
+                        elemType = PS_TYPE_F32;
+                    } else if(!strncmp(strType, "psF64", 5)) {
+                        elemType = PS_TYPE_F64;
+                    } else {
+                        status = PS_PARSE_ERROR_TYPE;
+                    }
+
+                    // Realloc number of columns as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorAlloc(0, elemType);
+                    } else {
+                        values = psArrayRealloc(values, numCols-1);
+                        values->n = values->nalloc;
+                        values->data[numCols-2] = psVectorAlloc(0, elemType);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strType);
+                }
+            } else {
+
+                // Parse and add values to all columns
+                numRows++;
+                numCols = 0;
+                while((strValue=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+
+                    // Realloc number of rows as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorRecycle(indexVec, numRows, indexVec->type.type);
+                        parseValue(indexVec, numRows-1, strValue, &status);
+                    } else {
+                        valuesVec = values->data[numCols-2];
+                        valuesVec = psVectorRecycle(valuesVec, numRows, valuesVec->type.type);
+                        parseValue(valuesVec, numRows-1, strValue, &status);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strValue);
+                } // end while
+            } // end else
+        } // if ignoreLine
+    } // end while
+
+    psFree(line);
+
+    // Set table for return
+    table->numRows = numRows;
+    table->numCols = numCols-1;
+    table->index = indexVec;
+    table->values = values;
+
+    fclose(fp);
+
+    return table;
+}
+
+psF64 psLookupTableInterpolate(psLookupTable *table, psF64 index, psU64 column, psLookupStatusType *status)
+{
+    psU64 hiIdx = 0;
+    psU64 loIdx = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psF64 out = 0.0;
+    psF64 denom = 0.0;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,0.0);
+    indexVec = table->index;
+    values = table->values;
+    numRows = table->numRows;
+    numCols = table->numCols;
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+    PS_PTR_CHECK_NULL(values,0.0);
+    PS_INT_CHECK_EQUALS(numRows, 0,0.0);
+    PS_INT_CHECK_EQUALS(numCols, 0,0.0);
+    PS_INT_CHECK_RANGE(column, 0, numCols-1, 0.0);
+
+
+    valuesVec = (psVector*)values->data[column];
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+
+    if(index<indexVec->data.F64[0] || index<table->validFrom) {
+
+        // Index value past top of table
+        *status = PS_LOOKUP_PAST_TOP;
+        return valuesVec->data.F64[0];
+    } else if(index>indexVec->data.F64[numRows-1] || index>table->validTo) {
+
+        // Index value past bottom of table
+        *status = PS_LOOKUP_PAST_BOTTOM;
+        return valuesVec->data.F64[numRows-1];
+    } else {
+
+        // Interpolation
+        while(index > indexVec->data.F64[hiIdx]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH, hiIdx);
+                *status = PS_LOOKUP_ERROR;
+                return 0.0;
+            }
+        }
+
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW, loIdx);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        }
+
+        denom = indexVec->data.F64[hiIdx] - indexVec->data.F64[loIdx];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        } else {
+            out = valuesVec->data.F64[loIdx]+(valuesVec->data.F64[hiIdx]-valuesVec->data.F64[loIdx])
+                  *(index-indexVec->data.F64[loIdx])/denom;
+        }
+    }
+
+    return out;
+}
+
+psVector* psLookupTableInterpolateAll(psLookupTable *table, psF64 index, psVector *stats)
+{
+    psU64 i = 0;
+    psU64 numCols = 0;
+    psVector *outVector = NULL;
+    psLookupStatusType status = PS_LOOKUP_SUCCESS;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(stats,NULL);
+    numCols = table->numCols;
+    PS_INT_CHECK_EQUALS(numCols, 0,NULL);
+
+    outVector = psVectorAlloc(numCols, PS_TYPE_F64);
+
+    // Fill vectors with results and status of results
+    for(i=0; i<numCols; i++) {
+        outVector->data.F64[i] = psLookupTableInterpolate(table, index, i, &status);
+        stats->data.U32[i] = status;
+    }
+
+    return outVector;
+}
+
Index: /branches/rel4/psLib/src/dataIO/psLookupTable.h
===================================================================
--- /branches/rel4/psLib/src/dataIO/psLookupTable.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataIO/psLookupTable.h	(revision 3057)
@@ -0,0 +1,112 @@
+/** @file  psLookupTable.h
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-11-09 00:38:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_LOOKUPTABLE_H
+#define PS_LOOKUPTABLE_H
+
+#include "psType.h"
+#include "psVector.h"
+#include "psArray.h"
+
+
+/** Lookup table structure
+ *
+ *  Holds table data read from external data files.
+ *
+ */
+typedef struct
+{
+    const char *fileName;              ///< Name of file with table
+    psU64 numRows;                     ///< Number of table rows
+    psU64 numCols;                     ///< Number of table columns
+    psF64 validFrom;                   ///< Lower bound for rable read
+    psF64 validTo;                     ///< Upper bound for table read
+    psVector *index;                   ///< Vector of independent index values
+    psArray *values;                   ///< Array of dependent table values corresponding to index values
+}
+psLookupTable;
+
+
+/** Lookup table lookup status and error conditions
+ *
+ *  Success, failure, and status conditions for table lookups.
+ */
+typedef enum {
+    PS_LOOKUP_SUCCESS             = 0x0000,        ///< Table lookup succeeded
+    PS_LOOKUP_PAST_TOP            = 0x0101,        ///< Lookup off top of table
+    PS_LOOKUP_PAST_BOTTOM         = 0x0102,        ///< Lookup off bottom of table
+    PS_LOOKUP_ERROR               = 0x0104         ///< Any other type of lookup error
+} psLookupStatusType;
+
+/** Lookup table parse status and error conditions
+ *
+ *  Success, failure, and status conditions for table parsing.
+ */
+typedef enum {
+    PS_PARSE_SUCCESS              = 0x0000,        ///< Table lookup succeeded
+    PS_PARSE_ERROR_TYPE           = 0x0101,        ///< Error parsing type
+    PS_PARSE_ERROR_VALUE          = 0x0102,        ///< Error parsing numerical value
+    PS_PARSE_ERROR_GENERAL        = 0x0104         ///< Any other type of lookup error
+}psParseErrorType;
+
+/** Allocator for psLookupTable struct
+ *
+ *  Allocates a new psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableAlloc(
+    const char *fileName,           ///< Name of file to read
+    psF64 validFrom,                ///< Lower bound for rable read
+    psF64 validTo                   ///< Upper bound for table read
+);
+
+/** Read lookup table
+ *
+ *  Reads a lookup table and fills corresponding psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableRead(
+    psLookupTable *table            ///< Table to read
+);
+
+/** Lookup and interpolate value from table.
+ *
+ *  Interpolates value from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psF64 psLookupTableInterpolate(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psU64 column,                   ///< Column in table to be interpolated
+    psLookupStatusType *status      ///< Status of lookup
+);
+
+/** Lookup and interpolate all values from table.
+ *
+ *  Interpolates all values from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psVector* psLookupTableInterpolateAll(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psVector *stats                 ///< Vector of status for each lookup
+);
+
+#endif
Index: /branches/rel4/psLib/src/dataManip/.cvsignore
===================================================================
--- /branches/rel4/psLib/src/dataManip/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/.cvsignore	(revision 3057)
@@ -0,0 +1,1 @@
+*.i
Index: /branches/rel4/psLib/src/dataManip/Makefile
===================================================================
--- /branches/rel4/psLib/src/dataManip/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/Makefile	(revision 3057)
@@ -0,0 +1,69 @@
+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 \
+           psRandom.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/rel4/psLib/src/dataManip/psConstants.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psConstants.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psConstants.h	(revision 3057)
@@ -0,0 +1,636 @@
+/** @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.53 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-10 19:47:11 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: Add parenthesis around all arguments so that these macros can be
+ *       called with complex expressions.
+ *
+ *
+ *
+ */
+
+/*****************************************************************************
+These constants are used by various functions in the psLib.
+ *****************************************************************************/
+#define PS_DETERMINE_BRACKET_STEP_SIZE 0.10
+#define PS_MAX_LMM_ITERATIONS 100
+#define PS_MAX_MINIMIZE_ITERATIONS 100
+#define PS_LEFT_SPLINE_DERIV 0.0
+#define PS_RIGHT_SPLINE_DERIV 0.0
+/*****************************************************************************
+These are common mathimatical constants used by various functions in the psLib.
+ *****************************************************************************/
+#define PS_ONE 1.0
+#define PS_PI   3.1415926535897932384626433832795029  /* pi */
+#define PS_PI_2 1.5707963267948966192313216916397514  /* pi/2 */
+#define PS_PI_4 0.7853981633974483096156608458198757  /* pi/4 */
+#define PS_1_PI 0.3183098861837906715377675267450287  /* 1/pi */
+#define PS_2_PI 0.6366197723675813430755350534900574  /* 2/pi */
+
+#define PS_COT(X) (1.0 / atan(X))
+#define DEG_TO_RAD(DEGREES) ((DEGREES) * M_PI / 180.0)
+#define MIN_TO_RAD(MINUTES) ((MINUTES) * M_PI / (180.0 * 60.0))
+#define SEC_TO_RAD(SECONDS) ((SECONDS) * M_PI / (180.0 * 60.0 * 60.0))
+#define RAD_TO_DEG(RADIANS) ((RADIANS) * 180.0 / M_PI)
+#define RAD_TO_MIN(RADIANS) ((RADIANS) * 180.0 * 60.0 / M_PI)
+#define RAD_TO_SEC(RADIANS) ((RADIANS) * 180.0 * 60.0 * 60.0 / M_PI)
+
+/*****************************************************************************
+ 
+*****************************************************************************/
+
+#define PS_INT_CHECK_EQUALS(NAME1, NAME2, RVAL) \
+if (NAME1 == NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_NON_EQUALS(NAME1, NAME2, RVAL) \
+if (NAME1 != NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are not equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_NON_NEGATIVE(NAME, RVAL) \
+if (NAME < 0) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is less than 0.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_POSITIVE(NAME, RVAL) \
+if (NAME < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is 0 or less.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_ZERO(NAME, RVAL) \
+if (NAME < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is 0.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_RANGE(NAME, LOWER, UPPER, RVAL) \
+if ((int)NAME < LOWER || (int)NAME > UPPER) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s, %d, is out of range.  Must be between %d and %d.", \
+            #NAME,(int)NAME,LOWER,UPPER); \
+    return RVAL; \
+}
+
+// Produce an error if (NAME1 > NAME2)
+#define PS_INT_COMPARE(NAME1, NAME2, RVAL) \
+if (NAME1 > NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: (%s > %s) (%d %d).", \
+            #NAME1, #NAME2, NAME1, NAME2); \
+    return(RVAL); \
+}
+
+
+// Produce an error if ((NAME1 > NAME2)
+#define PS_FLOAT_COMPARE(NAME1, NAME2, RVAL) \
+if (NAME1 > NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: (%s > %s) (%f %f)", \
+            #NAME1, #NAME2, NAME1, NAME2); \
+    return(RVAL); \
+}
+
+#define PS_FLOAT_CHECK_NON_EQUAL(NAME1, NAME2, RVAL) \
+if (fabs(NAME2 - NAME1) < FLT_EPSILON) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_FLOAT_CHECK_RANGE(NAME, LOWER, UPPER, RVAL) \
+if ((NAME) < (LOWER) || (NAME) > (UPPER)) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s, %f, is out of range.  Must be between %f and %f.", \
+            #NAME, NAME, LOWER, UPPER); \
+    return RVAL; \
+}
+
+/*****************************************************************************
+Macros which take a generic psLib type and determine if it is NULL, or has
+the wrong type.
+*****************************************************************************/
+#define PS_PTR_CHECK_NULL(NAME, RVAL) PS_PTR_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_PTR_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: %s is NULL.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_PTR_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_PTR_CHECK_DIMEN(NAME, DIMEN, RVAL) PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, return RVAL)
+#define PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, CLEANUP) \
+if (NAME->type.dimen != DIMEN) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect dimensionality.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_PTR_CHECK_DIMEN_GENERAL_NOT(NAME, DIMEN, CLEANUP) \
+if (NAME->type.dimen == DIMEN) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect dimensionality.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+
+#define PS_PTR_CHECK_SIZE_EQUAL(PTR1, PTR2, RVAL) \
+if (PTR1->n != PTR2->n) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "ptr %s has size %d, ptr %s has size %d.", \
+            #PTR1, PTR1->n, #PTR2, PTR2->n); \
+    return(RVAL); \
+}
+
+#define PS_PTR_CHECK_TYPE_EQUAL(PTR1, PTR2, RVAL) PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, return RVAL)
+
+#define PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, CLEANUP) \
+if (PTR1->type.type != PTR2->type.type) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "ptr %s has type %d, ptr %s has type %d.", \
+            #PTR1, PTR1->type.type, #PTR2, PTR2->type.type); \
+    CLEANUP; \
+}
+
+
+/*****************************************************************************
+    PS_VECTOR macros:
+ *****************************************************************************/
+#define PS_VECTOR_CHECK_NULL(NAME, RVAL) PS_VECTOR_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_VECTOR_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psVector %s or its data is NULL.", \
+            #NAME); \
+    CLEANUP; \
+} \
+
+#define PS_VECTOR_CHECK_EMPTY(NAME, RVAL) \
+if (NAME->n < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psVector %s has no elements.", \
+            #NAME); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE_F32_OR_F64(NAME, RVAL) \
+if ((NAME->type.type != PS_TYPE_F32) && (NAME->type.type != PS_TYPE_F64)) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "psVector %s: bad type(%d)", \
+            #NAME, NAME->type.type); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE_S16_S32_F32(NAME, RVAL) \
+if ((NAME->type.type != PS_TYPE_S16) && (NAME->type.type != PS_TYPE_S32) && (NAME->type.type != PS_TYPE_F32)) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "psVector %s: bad type(%d)", \
+            #NAME, NAME->type.type); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psVector %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_VECTOR_CHECK_SIZE_EQUAL(VEC1, VEC2, RVAL) \
+if (VEC1->n != VEC2->n) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "psVector %s has size %d, psVector %s has size %d.", \
+            #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(RVAL); \
+}
+
+#define PS_VECTOR_CHECK_TYPE_EQUAL(VEC1, VEC2, RVAL) \
+if (VEC1->type.type != VEC2->type.type) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "psVector %s has size %d, psVector %s has size %d.", \
+            #VEC1, VEC1->type.type, #VEC2, VEC2->type.type); \
+    return(RVAL); \
+}
+
+#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_VECTOR_PRINT_F32(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_CONVERT_F64_TO_F32_STATIC(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 PS_VECTOR_CONVERT_F32_TO_F64_STATIC(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 PS_VECTOR_GEN_YERR_STATIC_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 PS_VECTOR_GEN_YERR_STATIC_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 PS_VECTOR_GEN_X_INDEX_STATIC_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 PS_VECTOR_GEN_X_INDEX_STATIC_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 PS_VECTOR_GEN_STATIC_RECYCLED(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+NAME = psVectorRecycle(NAME, SIZE, TYPE); \
+p_psMemSetPersistent(NAME, true); \
+p_psMemSetPersistent(NAME->data.V, true); \
+
+#define PS_VECTOR_DECLARE_ALLOC_STATIC(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psVectorAlloc(SIZE, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_VECTOR_SET_U8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U8[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U16[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U32[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S8[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S16[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S32[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_F64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.F64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_F32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.F32[i] = VALUE; \
+}\
+
+
+/*****************************************************************************
+    PS_POLY macros:
+*****************************************************************************/
+#define PS_POLY_CHECK_NULL(NAME, RVAL) \
+if (NAME == NULL || NAME->coeff == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: polynomial %s or its coeffs is NULL.", \
+            #NAME); \
+    return(RVAL); \
+} \
+
+#define PS_POLY_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: polynomial %s has wrong type.", #NAME); \
+    return(RVAL); \
+} \
+
+// The following macros declare and allocate a static polynomial of the
+// specified order and type.
+
+#define PS_POLY_1D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial1D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial1DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+    p_psMemSetPersistent(NAME->coeff, true); \
+    p_psMemSetPersistent(NAME->coeffErr, true); \
+    p_psMemSetPersistent(NAME->mask, true); \
+} \
+
+#define PS_POLY_2D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial2D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial2DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_3D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial3D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial3DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_4D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial4D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial4DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_1D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial1D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial1DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_2D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial2D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial2DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_3D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial3D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial3DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_4D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial4D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial4DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+/*****************************************************************************
+    PS_IMAGE macros:
+*****************************************************************************/
+#define PS_IMAGE_CHECK_NULL(NAME, RVAL) PS_IMAGE_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_IMAGE_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psImage %s or its data is NULL.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_IMAGE_CHECK_EMPTY(NAME, RVAL) PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, return RVAL)
+#define PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, CLEANUP) \
+if (NAME->numCols < 1 || NAME->numRows < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImage %s has zero rows or columns (%dx%d).", \
+            #NAME, NAME->numCols, NAME->numRows); \
+    CLEANUP; \
+}
+
+#define PS_IMAGE_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psImage %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_CHECK_SIZE_EQUAL(NAME1, NAME2, RVAL) \
+if ((NAME1->numCols != NAME2->numCols) || \
+        (NAME1->numRows != NAME2->numRows)) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImages %s and %s are not the same size.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_CHECK_SIZE(NAME1, NUM_COLS, NUM_ROWS, RVAL) \
+if ((NAME1->numCols != NUM_COLS) || \
+        (NAME1->numRows != NUM_ROWS)) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImages %s is not the correct size.", \
+            #NAME1); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_PRINT_F32(NAME) \
+printf("======== printing %s ========\n", #NAME); \
+for (int i = 0 ; i < NAME->numRows ; i++) { \
+    for (int j = 0 ; j < NAME->numCols ; j++) { \
+        printf("%.2f ", NAME->data.F32[i][j]); \
+    } \
+    printf("\n"); \
+}\
+
+#define PS_IMAGE_SET_U8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U8[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U16[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U64[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S8[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S16[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S64[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_F32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.F32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_F64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.F64[i][j] = (VALUE); \
+    } \
+}\
+
+/*****************************************************************************
+    PS_READOUT macros:
+*****************************************************************************/
+#define PS_READOUT_CHECK_NULL(NAME, RVAL) \
+if (NAME == NULL || NAME->image == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psReadout %s or its data is NULL.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_READOUT_CHECK_EMPTY(NAME, RVAL) \
+if (NAME->image->numCols < 1 || NAME->image->numRows < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psReadout %s or its data is NULL.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_READOUT_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->image->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psImage %s has incorrect type.", #NAME); \
+    return(RVAL); \
+}
+
+/*****************************************************************************
+    Misc. macros:
+ *****************************************************************************/
+#define PS_MAX(A, B) \
+(((A) > (B)) ? (A) : (B)) \
+
+#define PS_MIN(A, B) \
+(((A) < (B)) ? (A) : (B)) \
+
+#define PS_SQR(A) \
+((A) * (A)) \
+
+#ifdef DARWIN
+#define PS_SQRT_F32(A) ((float) sqrt(A))
+#else
+#define PS_SQRT_F32(A) (sqrtf(A))
+#endif
Index: /branches/rel4/psLib/src/dataManip/psDataManipErrors.dat
===================================================================
--- /branches/rel4/psLib/src/dataManip/psDataManipErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psDataManipErrors.dat	(revision 3057)
@@ -0,0 +1,55 @@
+#
+#  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_TYPE_NOT_F32_C32           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.
+#
+psStats_NOT_F32_F64                    Invalid data type, %s.  Only psF32 and psF64 data types are supported.
+psStats_VECTOR_TYPE_UNSUPPORTED        Input psVector type, %s, is not supported.
+psStats_YVAL_OUT_OF_RANGE              Specified yVal, %g, is not within y-range, %g to %g.
+psStats_ROBUST_QUARTILE_BINS_FAILED    Could not determine the robust lower/upper quartile bin numbers.
+psStats_STATS_FAILED                   Failed to calculate the specified statistic.
+psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM            Failed to sort input data.
+psStats_STATS_VECTOR_BIN_DISECT_PROBLEM		Failed to determine the bin number of a data element.
+psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT Failed to fit a 1-dimensional polynomial to the three specified data points.  Returning NAN.
+psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN Failed to determine the median of the fitted polynomial.  Returning NAN.
+psStats_ROBUST_STATS_CLIPPED_STATS	Failed to determine clipped statistics.
+
+
+psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE The requested y-value does not fall with the specified range of x-values.  Returning NAN.
+#
+psFunctions_INVALID_POLYNOMIAL_TYPE    Unknown polynomial type 0x%x found.  Evaluation failed.
+psFunctions_TYPE_NOT_SUPPORTED         Input psVector type, %s, is not supported.
+psFunctions_NOT_ENOUGH_DATAPOINTS      Given vector does not have enough data points for %d-order interpolation.
+#
+psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE Unknown Random Number Generator Type
+psRandom_NULL_RANDOM_VAR               Random variable is NULL.
+#
+psMatrix_COUNT_DIFFERS                 Number of elements inconsistent, %d vs %d.  Number of elements must match.
+psMatrix_IMAGE_SIZE_DIFFERS            Specified psImage dimensions differed, %dx%d vs %dx%d.
+psMatrix_TYPE_MISMATCH                 Specified data type, %s, is not supported.
+psMatrix_MIN_COMPLEX_SUPPORT           The minimum operation is not supported with complex data.
+psMatrix_MAX_COMPLEX_SUPPORT           The maximum operation is not supported with complex data.
+psMatrix_OPERATION_UNSUPPORTED         Specified operation, %s, is not supported.
+psMatrix_DIMEN_OTHER_FOUND             %s's dimensionality is PS_DIMEN_OTHER, which is  not allowed.
+psMatrix_OUTPUT_VECTOR_NOT_CREATED     Couldn't create a proper output psVector.
+psMatrix_OUTPUT_IMAGE_NOT_CREATED      Couldn't create a proper output psImage.
+psMatrix_DIMEN_INVALID                 Specified parameter, %s, has invalid dimensionality, %d.
+psMatrix_VECTOR_EMPTY                  Input psVector contains no elements.  No data to perform operation with.
+psMatrix_IMAGE_EMPTY                   Input psImage contains no pixels.  No data to perform operation with.
+psMatrix_TRANSPOSE_MISMATCH            Number of rows do not match number of columns.
Index: /branches/rel4/psLib/src/dataManip/psDataManipErrors.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psDataManipErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psDataManipErrors.h	(revision 3057)
@@ -0,0 +1,73 @@
+/** @file  psDataManipErrors.h
+ *
+ *  @brief Contains the error text for the data manipulation functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-15 01:15:09 $
+ *
+ *  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_TYPE_NOT_F32_C32 "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."
+#define PS_ERRORTEXT_psStats_NOT_F32_F64 "Invalid data type, %s.  Only psF32 and psF64 data types are supported."
+#define PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED "Input psVector type, %s, is not supported."
+#define PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE "Specified yVal, %g, is not within y-range, %g to %g."
+#define PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED "Could not determine the robust lower/upper quartile bin numbers."
+#define PS_ERRORTEXT_psStats_STATS_FAILED "Failed to calculate the specified statistic."
+#define PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM "Failed to sort input data."
+#define PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM "Failed to determine the bin number of a data element."
+#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT "Failed to fit a 1-dimensional polynomial to the three specified data points.  Returning NAN."
+#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN "Failed to determine the median of the fitted polynomial.  Returning NAN."
+#define PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS "Failed to determine clipped statistics."
+#define PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE "The requested y-value does not fall with the specified range of x-values.  Returning NAN."
+#define PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE "Unknown polynomial type 0x%x found.  Evaluation failed."
+#define PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED "Input psVector type, %s, is not supported."
+#define PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS "Given vector does not have enough data points for %d-order interpolation."
+#define PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE "Unknown Random Number Generator Type"
+#define PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR "Random variable is NULL."
+#define PS_ERRORTEXT_psMatrix_COUNT_DIFFERS "Number of elements inconsistent, %d vs %d.  Number of elements must match."
+#define PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS "Specified psImage dimensions differed, %dx%d vs %dx%d."
+#define PS_ERRORTEXT_psMatrix_TYPE_MISMATCH "Specified data type, %s, is not supported."
+#define PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT "The minimum operation is not supported with complex data."
+#define PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT "The maximum operation is not supported with complex data."
+#define PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED "Specified operation, %s, is not supported."
+#define PS_ERRORTEXT_psMatrix_DIMEN_OTHER_FOUND "%s's dimensionality is PS_DIMEN_OTHER, which is  not allowed."
+#define PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED "Couldn't create a proper output psVector."
+#define PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED "Couldn't create a proper output psImage."
+#define PS_ERRORTEXT_psMatrix_DIMEN_INVALID "Specified parameter, %s, has invalid dimensionality, %d."
+#define PS_ERRORTEXT_psMatrix_VECTOR_EMPTY "Input psVector contains no elements.  No data to perform operation with."
+#define PS_ERRORTEXT_psMatrix_IMAGE_EMPTY "Input psImage contains no pixels.  No data to perform operation with."
+#define PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH "Number of rows do not match number of columns."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/dataManip/psFunctions.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psFunctions.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psFunctions.c	(revision 3057)
@@ -0,0 +1,2216 @@
+/** @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.83 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: What happens if the polyEVal functions are called with data of the wrong
+ *       type?
+ *  XXX: Should the "coeffErr[]" be used as well?  Bug ???.  Ignore coeffErr
+ *
+ */
+/*****************************************************************************/
+/*  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 "psLogMsg.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+#include "psDataManipErrors.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* 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);
+static void spline1DFree(psSpline1D *tmpSpline);
+static psS32 vectorBinDisectF32(psF32 *bins,psS32 numBins,psF32 x);
+static psS32 vectorBinDisectS32(psS32 *bins,psS32 numBins,psS32 x);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+static void spline1DFree(psSpline1D *tmpSpline)
+{
+    psS32 i;
+
+    if (tmpSpline == NULL) {
+        return;
+    }
+
+    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);
+
+    return;
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+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(psS32 maxChebyPoly)
+{
+    PS_INT_CHECK_NON_NEGATIVE(maxChebyPoly, NULL);
+
+    psPolynomial1D **chebPolys = NULL;
+    psS32 i = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF32 ordPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "---- Calling ordPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 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?
+// XXX: We assume that x is scaled between -1.0 and 1.0;
+static psF32 chebPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF32 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);
+
+    /*
+
+    psS32 n;
+    psS32 i;
+    psF32 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]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+static psF32 ordPolynomial2DEval(psF32 x,
+                                 psF32 y,
+                                 const psPolynomial2D* myPoly)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial2DEval(psF32 x, psF32 y, const psPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 wSum = 1.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF64 dOrdPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 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?
+static psF64 dChebPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF64 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);
+}
+
+static psF64 dOrdPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 wSum = 1.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+
+/*****************************************************************************
+fullInterpolate1DF32(): 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?
+ *****************************************************************************/
+#define FUNC_MACRO_FULL_INTERPOLATE_1D(TYPE) \
+static psF32 fullInterpolate1D##TYPE(ps##TYPE *domain, \
+                                     ps##TYPE *range, \
+                                     psS32 n, \
+                                     ps##TYPE x) \
+{ \
+    \
+    psS32 i; \
+    psS32 m; \
+    static psVector *p = NULL; \
+    p = psVectorRecycle(p, n, PS_TYPE_##TYPE); \
+    p_psMemSetPersistent(p, true); \
+    p_psMemSetPersistent(p->data.TYPE, true); \
+    \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n); \
+    \
+    for (i=0;i<n;i++) { \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "domain/range is (%f %f)\n", domain[i], range[i]); \
+    } \
+    \
+    for (i=0;i<n;i++) { \
+        p->data.TYPE[i] = range[i]; \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[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.TYPE[i] = (((x-domain[i+m]) * p->data.TYPE[i]) + \
+                               ((domain[i]-x) * p->data.TYPE[i+1])) / \
+                              (domain[i] - domain[i+m]); \
+            /*printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.TYPE[i], domain[i], x, p->data.TYPE[i+1], domain[i], domain[i+m]); \
+             */ \
+            psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                    "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[i]); \
+        } \
+    } \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() end ----\n"); \
+    \
+    return(p->data.TYPE[0]); \
+} \
+
+/*
+FUNC_MACRO_FULL_INTERPOLATE_1D(U8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(F64)
+*/
+FUNC_MACRO_FULL_INTERPOLATE_1D(F32)
+
+
+/*****************************************************************************
+interpolate1DF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+static psF32 interpolate1DF32(psF32 *domain,
+                              psF32 *range,
+                              psS32 n,
+                              psS32 order,
+                              psF32 x)
+{
+    PS_PTR_CHECK_NULL(domain, NAN)
+    PS_PTR_CHECK_NULL(range, NAN)
+    // XXX: Check valid values for n, order, and x?
+
+    psS32 binNum;
+    psS32 numIntPoints = order+1;
+    psS32 origin;
+
+    psTrace(".psLib.dataManip.psFunctions.interpolate1DF32", 4,
+            "---- interpolate1DF32() begin ----\n");
+
+    binNum = vectorBinDisectF32(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.interpolate1DF32", 4,
+            "---- interpolate1DF32() end ----\n");
+    return(fullInterpolate1DF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************/
+/*  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]
+ *****************************************************************************/
+psF32 psGaussian(psF32 x, psF32 mean, psF32 sigma, psBool normal)
+{
+    psF32 tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        tmp = 1.0 / PS_SQRT_F32(2.0 * M_PI * (sigma * sigma));
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    p_psGaussianDev()
+ This private routine (formerly a psLib API 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.
+ 
+XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* p_psGaussianDev(psF32 mean, psF32 sigma, psS32 Npts)
+{
+    PS_INT_CHECK_NON_NEGATIVE(Npts, NULL);
+
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    psS32 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);
+    }
+
+    // XXX: Should I free r, T as well?  This is a memory leak.
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(psS32 n,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->coeffErr = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->coeffErr = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->coeffErr[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->coeffErr = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->coeffErr[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->coeffErr[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->coeffErr = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->coeffErr[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->coeffErr[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->coeffErr[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+psF32 psPolynomial1DEval(const psPolynomial1D* myPoly, psF32 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial1DEvalVector(const psPolynomial1D *myPoly,
+                                   const psVector *x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(myPoly, x->data.F32[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial2DEval(const psPolynomial2D* myPoly, psF32 x, psF32 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial2DEvalVector(const psPolynomial2D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial3DEval(const psPolynomial3D* myPoly, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial3DEvalVector(const psPolynomial3D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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);
+}
+
+psF32 psPolynomial4DEval(const psPolynomial4D* myPoly, psF32 w, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial4DEvalVector(const psPolynomial4D *myPoly,
+                                   const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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(psS32 n,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->coeffErr = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->coeffErr = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->coeffErr[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->coeffErr = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->coeffErr[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->coeffErr[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->coeffErr = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->coeffErr[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->coeffErr[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->coeffErr[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+
+psF64 psDPolynomial1DEval(const psDPolynomial1D* myPoly, psF64 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial1DEvalVector(const psDPolynomial1D *myPoly,
+                                    const psVector *x)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(myPoly,
+                                               x->data.F64[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial2DEval(const psDPolynomial2D* myPoly,
+                          psF64 x,
+                          psF64 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial2DEvalVector(const psDPolynomial2D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial3DEval(const psDPolynomial3D* myPoly,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial3DEvalVector(const psDPolynomial3D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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);
+}
+
+psF64 psDPolynomial4DEval(const psDPolynomial4D* myPoly,
+                          psF64 w,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial4DEvalVector(const psDPolynomial4D *myPoly,
+                                    const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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 {
+//    psS32 n;
+//    psPolynomial1D **spline;
+//    psF32 *p_psDeriv2;
+//    psF32 *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(psS32 numSplines,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max)
+{
+    PS_INT_CHECK_NON_NEGATIVE(numSplines, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_FLOAT_CHECK_NON_EQUAL(max, min, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psF32 tmpDomain;
+    psF32 width;
+
+    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 = (psF32 *) psAlloc((numSplines+1) * sizeof(psF32));
+    width = (max - min) / ((psF32) 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;
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order)
+{
+    PS_VECTOR_CHECK_NULL(bounds, NULL);
+    PS_VECTOR_CHECK_EMPTY(bounds, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psS32 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);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (psF32 *) psAlloc((bounds->n) * sizeof(psF32));
+
+    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])) {
+                psError(PS_ERR_UNKNOWN, true, "data points must be distinct\n");
+            }
+        }
+    }
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+/*****************************************************************************
+vectorBinDisectF32(): This is a macro for a private function which takes as
+input a vector an array of data as well as a single value for that data.  The
+input vector values are assumed to be non-decreasing (v[i-1] <= v[i] for all
+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).
+ *****************************************************************************/
+#define FUNC_MACRO_VECTOR_BIN_DISECT(TYPE) \
+static psS32 vectorBinDisect##TYPE(ps##TYPE *bins, \
+                                   psS32 numBins, \
+                                   ps##TYPE x) \
+{ \
+    psS32 min; \
+    psS32 max; \
+    psS32 mid; \
+    \
+    psTrace(".psLib.dataManip.psFunctions.vectorBinDisect##TYPE", 4, \
+            "---- Calling vectorBinDisect##TYPE(%f)\n", x); \
+    \
+    if (x < bins[0]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, x, bins[0], bins[numBins-1]); \
+        return(-2); \
+    } \
+    \
+    if (x > bins[numBins-1]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, 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.vectorBinDisect##TYPE", 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.vectorBinDisect##TYPE", 4, \
+                    "---- Exiting vectorBinDisect##TYPE(): 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.vectorBinDisect##TYPE", 4, \
+            "---- Exiting vectorBinDisect##TYPE(): bin %d\n", min); \
+    return(min); \
+} \
+
+FUNC_MACRO_VECTOR_BIN_DISECT(S8)
+FUNC_MACRO_VECTOR_BIN_DISECT(S16)
+FUNC_MACRO_VECTOR_BIN_DISECT(S32)
+FUNC_MACRO_VECTOR_BIN_DISECT(S64)
+FUNC_MACRO_VECTOR_BIN_DISECT(U8)
+FUNC_MACRO_VECTOR_BIN_DISECT(U16)
+FUNC_MACRO_VECTOR_BIN_DISECT(U32)
+FUNC_MACRO_VECTOR_BIN_DISECT(U64)
+FUNC_MACRO_VECTOR_BIN_DISECT(F32)
+FUNC_MACRO_VECTOR_BIN_DISECT(F64)
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(bins, -4);
+    PS_VECTOR_CHECK_EMPTY(bins, -4);
+    PS_PTR_CHECK_NULL(x, -6);
+    PS_PTR_CHECK_TYPE_EQUAL(x, bins, -3);
+    psS8* strType;
+
+    switch (x->type.type) {
+    case PS_TYPE_U8:
+        return(vectorBinDisectU8(bins->data.U8, bins->n, x->data.U8));
+    case PS_TYPE_U16:
+        return(vectorBinDisectU16(bins->data.U16, bins->n, x->data.U16));
+    case PS_TYPE_U32:
+        return(vectorBinDisectU32(bins->data.U32, bins->n, x->data.U32));
+    case PS_TYPE_U64:
+        return(vectorBinDisectU64(bins->data.U64, bins->n, x->data.U64));
+    case PS_TYPE_S8:
+        return(vectorBinDisectS8(bins->data.S8, bins->n, x->data.S8));
+    case PS_TYPE_S16:
+        return(vectorBinDisectS16(bins->data.S16, bins->n, x->data.S16));
+    case PS_TYPE_S32:
+        return(vectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    case PS_TYPE_S64:
+        return(vectorBinDisectS64(bins->data.S64, bins->n, x->data.S64));
+    case PS_TYPE_F32:
+        return(vectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    case PS_TYPE_F64:
+        return(vectorBinDisectF64(bins->data.F64, bins->n, x->data.F64));
+    case PS_TYPE_C32:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_C64:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_PTR:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_BOOL:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+    return(-3);
+}
+
+/*****************************************************************************
+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: 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,
+                                psS32 order,
+                                psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(domain, NULL);
+    PS_VECTOR_CHECK_NULL(range, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, x, NULL);
+
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if (order > (domain->n - 1)) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS,
+                order);
+        return(NULL);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(interpolate1DF32(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((psF64)
+                                            interpolate1DF32(domain32->data.F32,
+                                                             range32->data.F32,
+                                                             domain32->n,
+                                                             order,
+                                                             (psF32) 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 {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "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
+(vectorBinDisectF32()).  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.
+ *****************************************************************************/
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NAN);
+    PS_INT_CHECK_NON_NEGATIVE(spline->n, NAN);
+
+    psS32 binNum;
+    psS32 n;
+
+    n = spline->n;
+    binNum = vectorBinDisectF32(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(spline->spline[0],
+                                      x));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(spline->spline[n-1],
+                                      x));
+        }
+    }
+
+    return(psPolynomial1DEval(spline->spline[binNum],
+                              x));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+
+    psS32 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,
+                                         (psF32) x->data.F64[i]
+                                     );
+        }
+    } else {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel4/psLib/src/dataManip/psFunctions.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psFunctions.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psFunctions.h	(revision 3057)
@@ -0,0 +1,437 @@
+/** @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 GLG, MHPCC
+*
+*  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-29 22:15:51 $
+*
+*  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 psF32      value on the gaussian curve given the input parameters
+ */
+psF32 psGaussian(
+    psF32 x,                           ///< Value at which to evaluate
+    psF32 mean,                        ///< Mean for the Gaussian
+    psF32 stddev,                      ///< Standard deviation for the Gaussian
+    psBool 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* p_psGaussianDev(
+    psF32 mean,                        ///< The mean of the Gaussian
+    psF32 sigma,                       ///< The sigma of the Gaussian
+    psS32 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
+    psS32 n;                             ///< Number of terms
+    psF32 *coeff;                      ///< Coefficients
+    psF32 *coeffErr;                   ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF32 **coeff;                     ///< Coefficients
+    psF32 **coeffErr;                  ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ***coeff;                    ///< Coefficients
+    psF32 ***coeffErr;                 ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ****coeff;                   ///< Coefficients
+    psF32 ****coeffErr;                ///< Error in coefficients
+    psU8 ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    psS32 n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial1DEval(
+    const psPolynomial1D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x                           ///< location at which to evaluate
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial2DEval(
+    const psPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y                           ///< y location at which to evaluate
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial3DEval(
+    const psPolynomial3D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial4DEval(
+    const psPolynomial4D* myPoly,       ///< Coefficients for the polynomial
+    psF32 w,                           ///< w location at which to evaluate
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+psVector *psPolynomial1DEvalVector(
+    const psPolynomial1D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psPolynomial2DEvalVector(
+    const psPolynomial2D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psPolynomial3DEvalVector(
+    const psPolynomial3D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psPolynomial4DEvalVector(
+    const psPolynomial4D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 n;                             ///< Number of terms
+    psF64 *coeff;                     ///< Coefficients
+    psF64 *coeffErr;                  ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF64 **coeff;                    ///< Coefficients
+    psF64 **coeffErr;                 ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ***coeff;                   ///< Coefficients
+    psF64 ***coeffErr;                ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ****coeff;                  ///< Coefficients
+    psF64 ****coeffErr;               ///< Error in coefficients
+    psU8 ****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(
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial1DEval(
+    const psDPolynomial1D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x                          ///< Value at which to evaluate
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial2DEval(
+    const psDPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF64 x,                           ///< Value x at which to evaluate
+    psF64 y            ///< Value y at which to evaluate
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial3DEval(
+    const psDPolynomial3D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial4DEval(
+    const psDPolynomial4D* myPoly,      ///< Coefficients for the polynomial
+    psF64 w,                          ///< Value w at which to evaluate
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+psVector *psDPolynomial1DEvalVector(
+    const psDPolynomial1D *myPoly, ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psDPolynomial2DEvalVector(
+    const psDPolynomial2D *myPoly,  ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psDPolynomial3DEvalVector(
+    const psDPolynomial3D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psDPolynomial4DEvalVector(
+    const psDPolynomial4D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+
+
+typedef struct
+{
+    psS32 n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    psF32 *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    psF32 *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(psS32 n,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order);
+
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+);
+
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+);
+
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                psS32 order,
+                                psScalar *x);
+
+psF32 p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         psF32 X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel4/psLib/src/dataManip/psMatrix.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMatrix.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMatrix.c	(revision 3057)
@@ -0,0 +1,626 @@
+/** @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.22 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 22:17:29 $
+ *
+ *  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"
+#include "psConstants.h"
+#include "psDataManipErrors.h"
+
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/** 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(PS_ERR_BAD_PARAMETER_TYPE, true,                                                        \
+            "Invalid operation. %s has incorrect dimensionality %d.", #NAME, PS_DIMEN);             \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type!=PS_TYPE_F64 && NAME->type.type!=PS_TYPE_F32) {                           \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true,                                                        \
+            "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(PS_ERR_BAD_PARAMETER_VALUE, true,                                                       \
+            "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(PS_ERR_BAD_PARAMETER_SIZE, true, "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;
+
+
+/*****************************************************************************/
+/* FILE STATIC FUNCTIONS                                                     */
+/*****************************************************************************/
+
+static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector);
+static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector);
+static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage);
+static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix);
+
+/** Static function to copy psF32 or psF64 vector data to a GSL vector */
+static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector)
+{
+    psU32 i = 0;
+    psU32 n = 0;
+
+
+    n = inVector->n;
+    for(i=0; i<n; i++) {
+        if(inVector->type.type == PS_TYPE_F32) {
+            outGslVector->data[i] = (psF64)inVector->data.F32[i];
+        } else {
+            outGslVector->data[i] = inVector->data.F64[i];
+        }
+    }
+}
+
+/** Static function to copy GSL vector data to a psF32 or psF64 vector */
+static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector)
+{
+    psU32 i = 0;
+    psU32 n = 0;
+
+
+    n = outVector->n;
+    for(i=0; i<n; i++) {
+        if(outVector->type.type == PS_TYPE_F32) {
+            outVector->data.F32[i] = (psF32)inGslVector->data[i];
+        } else {
+            outVector->data.F64[i] = inGslVector->data[i];
+        }
+    }
+}
+
+/** Static function to copy psF32 or psF64 image data to a GSL matrix */
+static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psU32 numRows = 0;
+    psU32 numCols = 0;
+
+
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    for(i=0; i<numRows; i++) {
+        for(j=0; j<numCols; j++) {
+            if(inImage->type.type == PS_TYPE_F32) {
+                outGslMatrix->data[i*numCols+j] = (psF64)inImage->data.F32[i][j];
+            } else {
+                outGslMatrix->data[i*numCols+j] = inImage->data.F64[i][j];
+            }
+        }
+    }
+}
+
+/** Static function to copy GSL matrix data to a psF32 or psF64 image */
+static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psU32 numRows = 0;
+    psU32 numCols = 0;
+
+
+    numRows = outImage->numRows;
+    numCols = outImage->numCols;
+    for(i=0; i<numRows; i++) {
+        for(j=0; j<numCols; j++) {
+            if(outImage->type.type == PS_TYPE_F32) {
+                outImage->data.F32[i][j] = (psF32)inGslMatrix->data[i*numCols+j];
+            } else {
+                outImage->data.F64[i][j] = inGslMatrix->data[i*numCols+j];
+            }
+        }
+    }
+}
+
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage* psMatrixLUD(psImage* outImage, psVector** outPerm, psImage* inImage)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *lu = NULL;
+    gsl_permutation perm;
+
+
+    #define psMatrixLUD_EXIT {psFree(outImage); return NULL;}
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL_GENERAL(inImage, psMatrixLUD_EXIT);
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_PTR_CHECK_NULL_GENERAL(outPerm, psMatrixLUD_EXIT);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    if (sizeof(size_t) == 4) {
+        *outPerm = psVectorRecycle(*outPerm, numCols, PS_TYPE_S32);
+    } else if (sizeof(size_t) == 8) {
+        *outPerm = psVectorRecycle(*outPerm, numCols, PS_TYPE_S64);
+    } else {
+        psError(PS_ERR_UNKNOWN, true,
+                "Failed to allocate the permutation vector; "
+                "could not determine the cooresponding data type.");
+        psMatrixLUD_EXIT;
+    }
+
+    (*outPerm)->n = numCols;
+    perm.data = (*outPerm)->data.V;
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Copy psImage data into GSL matrix data
+    psImageToGslMatrix(lu, inImage);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(lu, &perm, &signum);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, lu);
+
+    // Free GSL data
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, const psVector* inVector,
+                          const psVector* inPerm)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *lu;
+    gsl_permutation perm;
+    gsl_vector *b = NULL;
+    gsl_vector *x = NULL;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_IMAGE_CHECK_NULL(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_IMAGE_CHECK_EMPTY(inImage, outVector);
+    PS_VECTOR_CHECK_NULL(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_VECTOR_CHECK_NULL(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_VECTOR_CHECK_NULL(inPerm, outVector);
+    psVectorRecycle(outVector, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    lu = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+    b = gsl_vector_alloc(inVector->n);
+    psVectorToGslVector(b, inVector);
+    x = gsl_vector_alloc(inVector->n);
+
+    outVector->n = numCols;
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(lu, &perm, b, x);
+
+    // Copy GSL vector data to psVector data
+    gslVectorToPsVector(outVector, x);
+
+    // Free GSL data
+    gsl_vector_free(b);
+    gsl_vector_free(x);
+    gsl_matrix_free(lu);
+
+    return outVector;
+}
+
+psImage* psMatrixInvert(psImage* outImage, const psImage* inImage, psF32 *det)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *inv = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(det, outImage);
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+    inv = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+
+    // 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);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, inv);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+    gsl_matrix_free(inv);
+
+    return outImage;
+}
+
+psF32 *psMatrixDeterminant(const psImage* inImage)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    psF32 *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_IMAGE_CHECK_EMPTY(inImage, NULL);
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+
+    // Calculate determinant
+    det = (psF32*)psAlloc(sizeof(psF32));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (psF32)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)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *m1 = NULL;
+    gsl_matrix *m2 = NULL;
+    gsl_matrix *m3 = NULL;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_IMAGE_CHECK_NULL(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage1, outImage);
+    PS_IMAGE_CHECK_NULL(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    psImageRecycle(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+
+    // Initialize GSL data
+    m1 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m1, inImage1);
+    m2 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m2, inImage2);
+    m3 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m3, outImage);
+
+    // Perform multiplication
+    gsl_linalg_matmult(m1, m2, m3);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, m3);
+
+    // Free GSL structs
+    gsl_matrix_free(m1);
+    gsl_matrix_free(m2);
+    gsl_matrix_free(m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage* outImage, const psImage* inImage)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psS32 numRowsIn = 0;
+    psS32 numColsIn = 0;
+    psS32 numRowsOut = 0;
+    psS32 numColsOut = 0;
+
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    outImage = psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRowsIn = inImage->numRows;
+    numColsIn = inImage->numCols;
+    numRowsOut = outImage->numRows;
+    numColsOut = outImage->numCols;
+
+    if(numRowsIn!=numColsOut && numRowsOut!=numColsIn) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH);
+    }
+
+    if(outImage->type.type == PS_TYPE_F32) {
+        for(i=0; i<numRowsOut; i++) {
+            for(j=0; j<numColsOut; j++) {
+                outImage->data.F32[i][j] = inImage->data.F32[j][i];
+            }
+        }
+    } else {
+        for(i=0; i<numRowsOut; i++) {
+            for(j=0; j<numColsOut; j++) {
+                outImage->data.F64[i][j] = inImage->data.F64[j][i];
+            }
+        }
+    }
+
+    return outImage;
+}
+
+psImage* psMatrixEigenvectors(psImage* outImage, psImage* inImage)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix *out = NULL;
+    gsl_matrix *in = NULL;
+
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    in = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(in, inImage);
+    out = gsl_matrix_alloc(numRows, numCols);
+
+    // 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);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, out);
+
+    // Free GSL structs
+    gsl_matrix_free(in);
+    gsl_matrix_free(out);
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector* psMatrixToVector(psVector* outVector, const psImage* inImage)
+{
+    psS32 size = 0;
+
+    #define psMatrixToVector_EXIT {psFree(outVector); return NULL;}
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL_GENERAL(inImage, psMatrixToVector_EXIT);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_IMAGE_CHECK_EMPTY_GENERAL(inImage, psMatrixToVector_EXIT);
+
+    if (inImage->numRows == 1) {
+        // Create transposed row vector
+        psVectorRecycle(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if (inImage->numCols == 1) {
+        // Create non-transposed column vector
+        psVectorRecycle(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "Image does not have dim with 1 col or 1 row: (%d x %d).",
+                inImage->numRows, inImage->numCols);
+        return outVector;
+    }
+
+    PS_VECTOR_CHECK_NULL(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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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)
+{
+    psS32 size = 0;
+
+    // Error checks
+    PS_VECTOR_CHECK_NULL(inVector, outImage);
+
+    if (inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_VECTOR_CHECK_EMPTY(inVector, outImage);
+        psImageRecycle(outImage, 1, inVector->n, PS_TYPE_F64);
+        // More checks for PS_DIMEN_VECTOR
+        if (outImage->numCols > 1) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image has more than 1 column: numCols = %d.",
+                    outImage->numCols);
+            return outImage;
+        } else if (outImage->numRows != inVector->n) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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_VECTOR_CHECK_EMPTY(inVector, outImage);
+        psImageRecycle(outImage, inVector->n, 1, PS_TYPE_F64);
+        // More checks for PS_DIMEN_TRANSV
+        if (outImage->numRows > 1) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image has more than 1 row: numRows = %d.",
+                    outImage->numRows);
+            return outImage;
+        } else if (outImage->numCols != inVector->n) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image and vector sizes differ: (%d vs %d).",
+                    outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numCols;
+    }
+
+    PS_IMAGE_CHECK_NULL(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/rel4/psLib/src/dataManip/psMatrix.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMatrix.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMatrix.h	(revision 3057)
@@ -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.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 22:17:29 $
+ *
+ *  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
+    psF32 *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.
+ */
+psF32 *psMatrixDeterminant(
+    const psImage* 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/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 3057)
@@ -0,0 +1,905 @@
+/** @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.34 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17: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"
+#include "psConstants.h"
+#include "psDataManipErrors.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 */
+
+// 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)                                                                   \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 npt = 0;                                                                                             \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    npt  = ((psVector* )IN2)->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)                                                                    \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 j = 0;                                                                                               \
+    psS32 numRows = 0;                                                                                         \
+    psS32 numCols = 0;                                                                                         \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    numRows = ((psImage* )IN2)->numRows;                                                                     \
+    numCols = ((psImage* )IN2)->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)                                                                   \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 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)                                                                   \
+{                                                                                                            \
+    psS32 i = 0;                                                                                             \
+    psS32 n1 = 0;                                                                                            \
+    psS32 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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                             \
+                PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                         \
+                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)                                                                    \
+{                                                                                                            \
+    psS32 i = 0;                                                                                             \
+    psS32 j = 0;                                                                                             \
+    psS32 n1 = 0;                                                                                            \
+    psS32 numRows2 = 0;                                                                                      \
+    psS32 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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                         \
+                    PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                           \
+                    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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                 \
+                    PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                     \
+                    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)                                                                    \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 j = 0;                                                                                               \
+    psS32 numRows = 0;                                                                                         \
+    psS32 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)                                                                    \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 j = 0;                                                                                               \
+    psS32 n2 = 0;                                                                                              \
+    psS32 numRows1 = 0;                                                                                        \
+    psS32 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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                         \
+                    PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                     \
+                    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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                         \
+                    PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                     \
+                    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)                                                                     \
+{                                                                                                            \
+    psS32 i = 0;                                                                                               \
+    psS32 j = 0;                                                                                               \
+    psS32 numRows1 = 0;                                                                                        \
+    psS32 numCols1 = 0;                                                                                        \
+    psS32 numRows2 = 0;                                                                                        \
+    psS32 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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                             \
+                PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS,                                                     \
+                numCols1, numRows1, numCols2, numRows2);                                                     \
+        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:                                                                                                     \
+    /* char* strType; \
+    PS_TYPE_NAME(strType,IN1->type);                                                                         \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true,                                                                 \
+            PS_ERRORTEXT_psMatrix_TYPE_MISMATCH,                                                             \
+            strType);  */                                                                                      \
+    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,*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)) {                                                                            \
+    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(PS_ERR_BAD_PARAMETER_VALUE, true,                                                            \
+                PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT);                                                  \
+        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(PS_ERR_BAD_PARAMETER_VALUE, true,                                                            \
+                PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT);                                                  \
+        if (OUT != IN1 && OUT != IN2) {                                                                      \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    } else {                                                                                                 \
+        BINARY_TYPE(DIM1,DIM2,OUT,IN1,fmax(*i1,*i2),IN2);                                                    \
+    }                                                                                                        \
+} else {                                                                                                     \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true,                                                                \
+            PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED,                                                     \
+            OP);                                                                                             \
+    if (OUT != IN1 && OUT != IN2) {                                                                          \
+        psFree(OUT);                                                                                         \
+    }                                                                                                        \
+    return NULL;                                                                                             \
+}
+
+psPtr psBinaryOp(psPtr out, psPtr in1, char *op, psPtr in2)
+{
+
+    psVector* input1 = (psVector* ) in1;
+    psVector* input2 = (psVector* ) in2;
+
+    #define psBinaryOp_EXIT { \
+                              if (out != in1 && out != in2) { \
+                              psFree(out); \
+                              } \
+                              return NULL; \
+                            }
+
+    PS_PTR_CHECK_NULL_GENERAL(input1, psBinaryOp_EXIT);
+    PS_PTR_CHECK_NULL_GENERAL(input2, psBinaryOp_EXIT);
+    PS_PTR_CHECK_NULL_GENERAL(op, psBinaryOp_EXIT);
+
+    PS_PTR_CHECK_TYPE_EQUAL_GENERAL(input1,input2, psBinaryOp_EXIT);
+
+    PS_PTR_CHECK_DIMEN_GENERAL_NOT(input1, PS_DIMEN_OTHER, psBinaryOp_EXIT);
+    PS_PTR_CHECK_DIMEN_GENERAL_NOT(input2, PS_DIMEN_OTHER, psBinaryOp_EXIT);
+
+    psType* psType1 = (psType*)in1;
+    psType* psType2 = (psType*)in2;
+    psDimen dim1 = psType1->dimen;
+    psDimen dim2 = psType2->dimen;
+    psElemType elType1 = psType1->type;
+    psElemType elType2 = psType2->type;
+
+    if (dim1 == PS_DIMEN_VECTOR || dim1 == PS_DIMEN_TRANSV) {
+        if (((psVector* ) in1)->n == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, "Vector contains zero elements");
+        }
+    } else if (dim1 == PS_DIMEN_IMAGE) {
+        if (((psImage* ) in1)->numCols == 0 || ((psImage* ) in1)->numRows == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, "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, "Vector contains zero elements");
+        }
+    } else if (dim2 == PS_DIMEN_IMAGE) {
+        if (((psImage* ) in2)->numCols == 0 || ((psImage* ) in2)->numRows == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, "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(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED);
+                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(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED);
+                return NULL;
+            }
+            BINARY_OP(SCALAR, IMAGE, out, psType1, op, psType2);        // scalar op image
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psMatrix_DIMEN_INVALID,
+                    "in2",dim2);
+            psBinaryOp_EXIT;
+        }
+    } 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(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED);
+                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(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED);
+                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(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED);
+                return NULL;
+            }
+            BINARY_OP(VECTOR, IMAGE, out, psType1, op, psType2);        // vector op image
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psMatrix_DIMEN_INVALID,
+                    "in2",dim2);
+            psBinaryOp_EXIT;
+        }
+    } else if (dim1 == PS_DIMEN_IMAGE) {
+        out = psImageRecycle(out, ((psImage*)in1)->numCols, ((psImage*)in1)->numRows, elType1);
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED);
+            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 {
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psMatrix_DIMEN_INVALID,
+                    "in2",dim2);
+            psBinaryOp_EXIT;
+        }
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psMatrix_DIMEN_INVALID,
+                "in1",dim1);
+        psBinaryOp_EXIT;
+    }
+
+    // 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)                                                                               \
+{                                                                                                            \
+    psS32 i = 0;                                                                                             \
+    psS32 nIn = 0;                                                                                           \
+    psS32 nOut = 0;                                                                                          \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    nIn = ((psVector* )IN)->n;                                                                               \
+    nOut = ((psVector* )OUT)->n;                                                                             \
+    if(nIn != nOut) {                                                                                        \
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,                                                             \
+                PS_ERRORTEXT_psMatrix_COUNT_DIFFERS,                                                         \
+                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)                                                                                \
+{                                                                                                            \
+    psS32 i = 0;                                                                                             \
+    psS32 j = 0;                                                                                             \
+    psS32 numRowsIn = 0;                                                                                     \
+    psS32 numColsIn = 0;                                                                                     \
+    psS32 numRowsOut = 0;                                                                                    \
+    psS32 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(PS_ERR_BAD_PARAMETER_SIZE, true,                                                             \
+                PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS,                                                    \
+                numColsIn, numRowsIn, numColsOut, numRowsOut);                                               \
+        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: {                                                                                                     \
+        char* strType;                                                                                           \
+        PS_TYPE_NAME(strType, IN->type);                                                                         \
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,                                                                 \
+                PS_ERRORTEXT_psMatrix_TYPE_MISMATCH,                                                             \
+                strType);                                                                                        \
+        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(PS_ERR_BAD_PARAMETER_VALUE, true,                                                                \
+            PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED,                                                     \
+            OP);                                                                                             \
+    if (OUT != IN) {                                                                                         \
+        psFree(OUT);                                                                                         \
+    }                                                                                                        \
+    return NULL;                                                                                             \
+}
+
+psPtr psUnaryOp(psPtr out, psPtr in, char *op)
+{
+    #define psUnaryOp_EXIT { \
+                             if (out != in) { \
+                             psFree(out); \
+                             } \
+                             return NULL; \
+                           }
+
+    psType* psTypeIn = (psType* ) in;
+
+    PS_PTR_CHECK_NULL_GENERAL(in, psUnaryOp_EXIT);
+    PS_PTR_CHECK_NULL_GENERAL(op, psUnaryOp_EXIT);
+
+    psDimen dimIn = psTypeIn->dimen;
+    psElemType 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) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    PS_ERRORTEXT_psMatrix_VECTOR_EMPTY);
+            psUnaryOp_EXIT;
+        }
+
+        out = psVectorRecycle(out,
+                              ((psVector*)in)->n,
+                              elTypeIn);
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED);
+            psUnaryOp_EXIT;
+        }
+
+        UNARY_OP(VECTOR, out, psTypeIn, op);    // vector
+        break;
+    case PS_DIMEN_IMAGE:
+        if (((psImage* ) in)->numCols == 0 || ((psImage* ) in)->numRows == 0) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    PS_ERRORTEXT_psMatrix_IMAGE_EMPTY);
+            psUnaryOp_EXIT;
+        }
+
+        out = psImageRecycle(out,
+                             ((psImage*)in)->numCols,
+                             ((psImage*)in)->numRows,
+                             elTypeIn);
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED);
+            psUnaryOp_EXIT;
+        }
+
+        UNARY_OP(IMAGE, out, psTypeIn, op);     // image
+        break;
+    default:
+        if (out != in) {
+            psFree(out);
+        }
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psMatrix_DIMEN_INVALID,
+                "in", dimIn);
+        psUnaryOp_EXIT;
+    }
+
+    // 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/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 3057)
@@ -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.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
+ *
+ *  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 operations.
+ *
+ *  @return  psType* : Pointer to either psImage or psVector.
+ */
+psType* psBinaryOp(
+    psPtr out,                         ///< Output type, either psImage or psVector.
+    psPtr in1,                         ///< First input, either psImage or psVector.
+    char *op,                          ///< Operator.
+    psPtr 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(
+    psPtr out,                         ///< Output type, either psImage or psVector.
+    psPtr in,                          ///< Input, either psImage or psVector.
+    char *op                           ///< Operator.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/dataManip/psMinimize.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMinimize.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMinimize.c	(revision 3057)
@@ -0,0 +1,1853 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.101 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: must follow coding name standards on local functions.
+ *
+ */
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMinimize.h"
+#include "psStats.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+#define PS_SEG psLib
+#define PS_PWD dataManip
+#define PS_FILE psMinimize
+/*****************************************************************************/
+/* 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: Use a static vector.
+ *****************************************************************************/
+void psBuildSums1D(psF64 x,
+                   psS32 polyOrder,
+                   psVector* sums)
+{
+    psS32 i = 0;
+    psF64 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?
+ *****************************************************************************/
+psF32 *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");
+
+    psS32 i;
+    psS32 k;
+    psF32 sig;
+    psF32 p;
+    psS32 n = y->n;
+    psF32 *u = (psF32 *) psAlloc(n * sizeof(psF32));
+    psF32 *derivs2 = (psF32 *) psAlloc(n * sizeof(psF32));
+    psF32 *X = (psF32 *) & (x->data.F32[0]);
+    psF32 *Y = (psF32 *) & (y->data.F32[0]);
+    psF32 qn;
+
+    // XXX: The second derivatives at the endpoints, undefined in the SDR,
+    // are set in psConstants.h: PS_LEFT_SPLINE_DERIV, PS_RIGHT_SPLINE_DERIV.
+    derivs2[0] = -0.5;
+    u[0]= (3.0/(X[1]-X[0])) * ((Y[1]-Y[0])/(X[1]-X[0]) - PS_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])) * (PS_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]);
+    }
+
+    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: This is F32 only
+ *****************************************************************************/
+/*
+psF32 p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         psF32 X)
+{
+    PS_PTR_CHECK_NULL(spline, NAN);
+    PS_INT_CHECK_NON_NEGATIVE(spline->n, NAN);
+    PS_PTR_CHECK_NULL(spline->domains, NAN);
+    PS_PTR_CHECK_NULL(spline->p_psDeriv2, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(y, NAN);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NAN);
+ 
+    psS32 n;
+    psS32 klo;
+    psS32 khi;
+    psF32 H;
+    psF32 A;
+    psF32 B;
+    psF32 C;
+    psF32 D;
+    psF32 Y;
+ 
+    n = spline->n;
+    klo = p_psVectorBinDisect32(spline->domains, (spline->n)+1, X);
+    if (klo < 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: psMinimize.c: p_psNRSpline1DEval(): p_psVectorBinDisect32 returned an error (%d).\n", klo);
+        return(NAN);
+    }
+    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
+{
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(y, NULL);
+
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() begin ----\n");
+    psS32 numSplines = (y->n)-1;
+    psF32 tmp;
+    psF32 H;
+    psS32 i;
+    psF32 slope;
+    psVector *x32 = NULL;
+    psVector *y32 = NULL;
+    psVector *yErr32 = NULL;
+    static psVector *x32Static = NULL;
+    static psVector *y32Static = NULL;
+    static psVector *yErr32Static = NULL;
+
+    PS_VECTOR_CONVERT_F64_TO_F32_STATIC(y, y32, y32Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        PS_VECTOR_GEN_YERR_STATIC_F32(yErr32Static, y->n);
+        yErr32 = yErr32Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(yErr, NULL);
+        PS_VECTOR_CONVERT_F64_TO_F32_STATIC(yErr, yErr32, yErr32Static);
+    }
+
+    // If x==NULL, create an x32 vector with x values set to (0:n).
+    if (x == NULL) {
+        PS_VECTOR_GEN_X_INDEX_STATIC_F32(x32Static, y->n);
+        x32 = x32Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+        PS_VECTOR_CONVERT_F64_TO_F32_STATIC(x, x32, x32Static);
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(x32, y32, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(yErr32, y32, NULL);
+
+    /*
+        XXX:
+        This can not be implemented until SDR states what order spline should be
+        created.
+        Should we error if mySpline is not NULL?
+        Should we error if mySPline is not NULL?
+    */
+    if (mySpline == NULL) {
+        mySpline = psSpline1DAllocGeneric(x32, 3);
+    }
+    PS_PTR_CHECK_NULL(mySpline, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(mySpline->n, NULL);
+
+    if (y32->n != (1 + mySpline->n)) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "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",
+                x32->data.F32[i],
+                x32->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);
+}
+
+
+/******************************************************************************
+XXX: We assume unnormalized gaussians.
+ *****************************************************************************/
+psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss1D() begin ----\n");
+    psF32 x;
+    psS32 i;
+    psF32 mean = params->data.F32[0];
+    psF32 stdev = params->data.F32[1];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "(mean, stdev) is (%f, %f)\n", mean, stdev);
+
+    if (deriv == NULL) {
+        deriv = psImageAlloc(params->n, coords->n, PS_TYPE_F32);
+    } else {
+        PS_IMAGE_CHECK_SIZE(deriv, params->n, coords->n, NULL);
+        PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    }
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        out->data.F32[i] = psGaussian(x, mean, stdev, false);
+    }
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        psF32 tmp = (x - mean) * psGaussian(x, mean, stdev, false);
+        deriv->data.F32[i][0] = tmp / (stdev * stdev);
+        tmp = (x - mean) * (x - mean) *
+              psGaussian(x, mean, stdev, 0);
+        deriv->data.F32[i][1] = tmp / (stdev * stdev * stdev);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss1D() end ----\n");
+    return(out);
+}
+
+/*
+XXX: from bug 230:
+ 
+We first perform a rotation:
+u = - (x-x0)*cos(theta) + (y-y0)*sin(theta)
+v = (x-x0)*cos(theta) + (y-y0)*sin(theta)
+ 
+Here u is the major axis, and v is the minor axis, x0,y0 is the centre, and
+theta is the position angle.
+ 
+Then the flux is
+ 
+flux = norm * exp(-( u*u/2.0/sigmau/sigmau + v*v/2.0/sigmav/sigmav)
+)/2.0/pi/sigmau/sigmav
+ 
+Here sigmau and sigmav are the widths of the major and minor axes.
+ 
+The "norm" parameter in the equation above corresponds to the normalisation.
+ 
+Suggest order:
+ 
+norm
+x0
+y0
+sigma_u
+sigma_v
+theta
+*/
+
+psVector *psMinimizeLMChi2Gauss2D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psF64 normalization = params->data.F32[0];
+    psF64 x0 = params->data.F32[1];
+    psF64 y0 = params->data.F32[2];
+    psF64 sigmaX = params->data.F32[3];
+    psF64 sigmaY = params->data.F32[4];
+    psF64 theta = params->data.F32[5];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    if (deriv == NULL) {
+        deriv = psImageAlloc(params->n, coords->n, PS_TYPE_F32);
+    } else {
+        PS_IMAGE_CHECK_SIZE(deriv, 6, coords->n, NULL);
+        PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss2D() begin ----\n");
+
+    for (psS32 i=0;i<coords->n;i++) {
+        psF64 x = ((psVector *) coords->data[i])->data.F32[0];
+        psF64 y = ((psVector *) coords->data[i])->data.F32[0];
+
+        psF64 u = - (x-x0)*cos(theta) + (y-y0)*sin(theta);
+        psF64 v = (x-x0)*cos(theta) + (y-y0)*sin(theta);
+
+        psF64 flux = normalization * exp(-( u*u/(2.0 * sigmaX * sigmaX) +
+                                            v*v/(2.0 * sigmaY * sigmaY)))/
+                     (2.0 * M_PI * sigmaX * sigmaY);
+        out->data.F32[i] = flux;
+
+        // XXX: Calculate these correctly.
+        deriv->data.F32[i][0] = 0.0;
+        deriv->data.F32[i][1] = 0.0;
+        deriv->data.F32[i][2] = 0.0;
+        deriv->data.F32[i][3] = 0.0;
+        deriv->data.F32[i][4] = 0.0;
+        deriv->data.F32[i][5] = 0.0;
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss2D() end ----\n");
+    return(out);
+}
+
+/******************************************************************************
+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.
+ 
+XXX: Must update the covar matrix.
+ *****************************************************************************/
+psBool psMinimizeLMChi2(psMinimization *min,
+                        psImage *covar,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *x,
+                        const psVector *y,
+                        const psVector *yErr,
+                        psMinimizeLMChi2Func func)
+{
+    PS_PTR_CHECK_NULL(min, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_EMPTY(y, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(x, y, NULL);
+    PS_PTR_CHECK_NULL(func, NULL);
+
+    if (paramMask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(params, paramMask, NULL);
+    }
+    if (yErr != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(y, yErr, NULL);
+    }
+    if (covar != NULL) {
+        PS_IMAGE_CHECK_SIZE(covar, params->n, params->n, NULL);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2() begin ----\n");
+    psS32 numData = y->n;
+    psS32 numParams = params->n;
+    psS32 i;
+    psS32 j;
+    psS32 k;
+    psS32 l;
+    psS32 n;
+    psS32 p;
+    psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *perm = NULL;
+
+    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);
+    psImage *deriv = psImageAlloc(numParams, numData, PS_TYPE_F32);
+    psVector *currValueVec = NULL;
+    psVector *newValueVec = NULL;
+    psF32 currChi2 = 0.0;
+    psF32 newChi2 = 0.0;
+    psF32 lamda = 0.00005;
+    lamda = 0.05;
+
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "min->tol is %f\n", min->tol);
+
+    for (p=0;p<numParams;p++) {
+        origParams->data.F32[p] = params->data.F32[p];
+    }
+
+    min->lastDelta = PS_MAX_F32;
+    min->iter = 0;
+
+    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "------------------------------------------------------\n");
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
+
+        //
+        // Calculate the current values and chi-squared of the function.
+        //
+        currChi2 = 0.0;
+        currValueVec = func(deriv, params, x);
+        for (n=0;n<numData;n++) {
+            currChi2+= (currValueVec->data.F32[n] - y->data.F32[n]) *
+                       (currValueVec->data.F32[n] - y->data.F32[n]);
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "data[%d], chi2 calculation+= (%f - %f)^2\n", n,
+                    currValueVec->data.F32[n], y->data.F32[n]);
+        }
+
+        for (p=0;p<numParams;p++) {
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
+        }
+        psTrace(".psLib.dataManip.psMinimize", 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->data.F32[n][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])+=
+                    (y->data.F32[n] - currValueVec->data.F32[n]) *
+                    deriv->data.F32[n][p];
+            }
+            // XXX: multiply by -1 here?
+            (beta->data.F64[p])*= -1.0;
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
+        }
+        psFree(currValueVec);
+
+        //
+        // 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->data.F32[n][k] *
+                                            deriv->data.F32[n][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] =
+                        (psF64) ((1.0 + lamda) * alpha->data.F32[j][k]);
+                } else {
+                    A->data.F64[j][k] = (psF64) alpha->data.F32[j][k];
+                }
+            }
+        }
+        for (j=0;j<numParams;j++) {
+            psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n");
+            for (k=0;k<numParams;k++) {
+                psTrace(".psLib.dataManip.psMinimize", 6, "%f ", A->data.F64[j][k]);
+            }
+            psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n");
+        }
+
+        //
+        // Solve A * alpha = Beta
+        //
+        // XXX: How do we know if these functions were successful?
+        //
+        aOut = psMatrixLUD(aOut, &perm, A);
+        paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
+
+        //
+        // Mask any masked parameters.
+        //
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimize", 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] -
+                                         (psF32) paramDeltasF64->data.F64[i];
+            }
+        }
+
+        psTrace(".psLib.dataManip.psMinimize", 6,
+                "Calling func() with new parameters:\n");
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
+        }
+
+
+        //
+        // Calculate new function values.
+        //
+        newChi2 = 0.0;
+        newValueVec = func(deriv, newParams, x);
+        for (n=0;n<numData;n++) {
+            newChi2+= (newValueVec->data.F32[n] - y->data.F32[n]) *
+                      (newValueVec->data.F32[n] - y->data.F32[n]);
+
+        }
+        psFree(newValueVec);
+
+        psTrace(".psLib.dataManip.psMinimize", 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] = (psF32) newParams->data.F32[i];
+            }
+            lamda*= 0.1;
+            psTrace(".psLib.dataManip.psMinimize", 4, "*** Reducing lamda by factor of 10\n");
+        } else {
+            lamda*= 10.0;
+            psTrace(".psLib.dataManip.psMinimize", 4, "*** Increasing lamda by factor of 10\n");
+        }
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "lamda is %f\n", lamda);
+        min->iter++;
+    }
+    psFree(beta);
+    psFree(perm);
+    psFree(paramDeltasF64);
+    psFree(origParams);
+    psFree(newParams);
+    psFree(alpha);
+    psFree(A);
+    psFree(aOut);
+    psFree(deriv);
+
+    if ((min->iter < min->maxIter) ||
+            (min->lastDelta <= min->tol)) {
+        return(true);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+VectorFitPolynomial1DCheb():  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 *VectorFitPolynomial1DCheby(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    psS32 j;
+    psS32 k;
+    psS32 n = x->n;
+    psF64 fac;
+    psF64 sum;
+    PS_VECTOR_GEN_STATIC_RECYCLED(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.
+    psF64 min = -1.0;
+    psF64 max = 1.0;
+    psF64 bma = 0.5 * (max-min);  // 1
+    psF64 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 (psS32 i=0;i<n;i++) {
+        // NR 5.8.4
+        psF64 Y = cos(M_PI * (0.5 + ((psF32) i)) / ((psF32) n));
+        psF64 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.VectorFitPolynomial1DCheby", 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/((psF32) 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 * ((psF32) j) * (0.5 + ((psF32) k)) / ((psF32) n));
+        }
+
+        myPoly->coeff[j] = fac * sum;
+    }
+
+    return(myPoly);
+}
+
+/******************************************************************************
+VectorFitPolynomial1DOrd():  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* VectorFitPolynomial1DOrd(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    psS32 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;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 k = 0;
+    psVector* xSums = NULL;
+
+    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
+            "---- VectorFitPolynomial1DOrd() begin ----\n");
+    // printf("VectorFitPolynomial1D()\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);
+    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;
+        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++) {
+            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++) {
+            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];
+                }
+            }
+        }
+    }
+
+    // XXX: How do we know if these routines were successful?
+    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]);
+    }
+
+    psFree(A);
+    psFree(ALUD);
+    psFree(B);
+    psFree(coeffs);
+    psFree(X);
+    psFree(outPerm);
+    psFree(xSums);
+
+    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
+            "---- VectorFitPolynomial1DOrd() 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)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(myPoly->n, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_EMPTY(y, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(y, NULL);
+
+    psS32 i;
+    psVector *x64 = NULL;
+    psVector *y64 = NULL;
+    psVector *yErr64 = NULL;
+    static psVector *x64Static = NULL;
+    static psVector *y64Static = NULL;
+    static psVector *yErr64Static = NULL;
+
+    PS_VECTOR_CONVERT_F32_TO_F64_STATIC(y, y64, y64Static);
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        PS_VECTOR_GEN_YERR_STATIC_F64(yErr64Static, y->n);
+        yErr64 = yErr64Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(yErr, NULL);
+        PS_VECTOR_CONVERT_F32_TO_F64_STATIC(yErr, yErr64, yErr64Static);
+    }
+
+    // If x==NULL, create an x64 vector with x values set to (0:n).
+    if (x == NULL) {
+        PS_VECTOR_GEN_X_INDEX_STATIC_F64(x64Static, y->n);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVectorRangeF64(x64Static, -1.0, 1.0);
+        }
+        x64 = x64Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+        PS_VECTOR_CONVERT_F32_TO_F64_STATIC(x, x64, x64Static);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVectorRangeF64(x64, -1.0, 1.0);
+        }
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(x64, y64, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(yErr64, y64, NULL);
+
+    // Call the appropriate vector fitting routine.
+    psPolynomial1D *rc = NULL;
+    if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        rc = VectorFitPolynomial1DCheby(myPoly, x64, y64, yErr64);
+    } else if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        rc = VectorFitPolynomial1DOrd(myPoly, x64, y64, yErr64);
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "unknown polynomial type.\n");
+        return(NULL);
+    }
+    if (rc == NULL) {
+        psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    return(myPoly);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+psMinimization *psMinimizationAlloc(psS32 maxIter,
+                                    psF32 tol)
+{
+    PS_INT_CHECK_NON_NEGATIVE(maxIter, NULL);
+
+    psMinimization *min = psAlloc(sizeof(psMinimization));
+    min->maxIter = maxIter;
+    min->tol = tol;
+    min->value = 0.0;
+    min->iter = 0;
+    min->lastDelta = 0.0;
+
+    return(min);
+}
+
+// This macro takes as input the vector BASE and adds a multiple of the vector
+// LINE to it.  We assume BASEMASK is non-null.
+#define PS_VECTOR_ADD_MULTIPLE(BASE, BASEMASK, LINE, OUT, MUL) \
+for (psS32 i=0;i<BASE->n;i++) { \
+    if (BASEMASK->data.U8[i] == 0) { \
+        OUT->data.F32[i] = BASE->data.F32[i] + (MUL * LINE->data.F32[i]); \
+    } else { \
+        OUT->data.F32[i] = BASE->data.F32[i]; \
+    } \
+} \
+
+#define PS_VECTOR_F32_CHECK_ZERO_VECTOR(IN, BOOL_VAR) \
+BOOL_VAR = true; \
+for (psS32 i=0;i<IN->n;i++) { \
+    if (fabs(IN->data.F32[i]) >= FLT_EPSILON) { \
+        BOOL_VAR = false; \
+        break; \
+    } \
+} \
+
+#define PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(IN, INMASK, BOOL_VAR) \
+BOOL_VAR = true; \
+for (psS32 i=0;i<IN->n;i++) { \
+    if ((INMASK->data.U8[i] == 0) && (fabs(IN->data.F32[i]) >= FLT_EPSILON)) { \
+        BOOL_VAR = false; \
+        break; \
+    } \
+} \
+
+
+/******************************************************************************
+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) < f(param + a * line)
+f(param + b * line) < f(param + c * line)
+a < b < c
+ 
+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.
+ 
+XXX:
+output bracket vector should be an input as well.
+*****************************************************************************/
+psVector *p_psDetermineBracket(psVector *params,
+                               psVector *line,
+                               const psVector *paramMask,
+                               const psArray *coords,
+                               psMinimizePowellFunc func)
+{
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psS32 iter = 100;
+    psF32 aDir = 0.0;
+    psF32 cDir = 0.0;
+    psF32 new_aDir = 0.0;
+    psF32 new_cDir = 0.0;
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    psF32 stepSize = PS_DETERMINE_BRACKET_STEP_SIZE;
+    psVector *tmp = NULL;
+    psBool boolLineIsNull = true;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    // If the line vector is zero, then return NULL.
+    PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(params, paramMask, boolLineIsNull);
+    if (boolLineIsNull == true) {
+        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;
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, a);
+    fa = func(tmp, coords);
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, b);
+    fb = func(tmp, coords);
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+    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;
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, a);
+        fa = func(tmp, coords);
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+        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);
+}
+
+
+#define RETURN_FINAL_BRACKET(d) \
+if (a < c) { \
+    bracket->data.F32[0] = a; \
+    bracket->data.F32[1] = b; \
+    bracket->data.F32[2] = c; \
+} else { \
+    bracket->data.F32[0] = c; \
+    bracket->data.F32[1] = b; \
+    bracket->data.F32[2] = a; \
+} \
+psTrace(".psLib.dataManip.p_psDetermineBracket", 4, \
+        "---- p_psDetermineBracket() end ----\n"); \
+psTrace(".psLib.dataManip.p_psDetermineBracket", 4, "Final bracket (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", a, b, c, fa, fb, fc); \
+return(bracket); \
+
+#define PS_DETERMINE_BRACKET_MAX_ITERATIONS 100
+psVector *p_psDetermineBracket2(psVector *params,
+                                psVector *line,
+                                const psVector *paramMask,
+                                const psArray *coords,
+                                psMinimizePowellFunc func)
+{
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psS32 iter = 0;
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmp, params->n, PS_TYPE_F32);
+    psBool boolLineIsNull = true;
+    psF32 prevMin = 0.0;
+    psS32 countMin = 0;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    // If the line vector is zero, then return NULL.
+    PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(params, paramMask, boolLineIsNull);
+    if (boolLineIsNull == true) {
+        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");
+        return(NULL);
+    }
+
+    // We determine in what x-direction does the function decrease.
+    a = 0.0;
+    fa = func(params, coords);
+    b = 0.5;
+    iter = 0;
+    do {
+        b*= (1.0 + PS_DETERMINE_BRACKET_STEP_SIZE);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, b);
+        fb = func(tmp, coords);
+    } while ((fabs(fb - fa) < FLT_EPSILON) && (iter++ < 100));
+
+    if (fb > fa) {
+        a = b;
+        fa = fb;
+        b = 0.0;
+        fb = func(params, coords);
+    }
+    c = b;
+
+    // At this point we have (a, b) and we know that (fa >= fb).  Initially, c=b;
+    // We keep stretching b out further from "a" until (fc > previous fc).  If
+    // that happens, then we have our bracket.
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    iter = 0;
+    while (iter < PS_DETERMINE_BRACKET_MAX_ITERATIONS) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "psDetermineBracket(): iterationA %d\n", iter);
+        c+= (1.0 + PS_DETERMINE_BRACKET_STEP_SIZE) * (c - a);
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+        fc = func(tmp, coords);
+
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "Iteration(%d) (bracket): (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", iter, a, b, c, fa, fb, fc);
+
+        if ((fb < fa) && (fb < fc)) {
+            RETURN_FINAL_BRACKET();
+        } else {
+            b = c;
+            fb = fc;
+        }
+
+        // This code maintains a count of how many times the minimum fc has
+        // stayed the same.  If it gets too high, we exit this loop.
+        if (fc == prevMin) {
+            countMin++;
+        } else {
+            countMin = 0;
+        }
+        prevMin = fc;
+        if (countMin == 10) {
+            RETURN_FINAL_BRACKET();
+        }
+
+        iter++;
+    }
+
+    psFree(bracket);
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() end (NULL) (BAD) ----\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
+XXX: Since this is an internal function, many of the parameter checks are
+     redundant.
+ *****************************************************************************/
+#define PS_LINEMIN_MAX_ITERATIONS 30
+psF32 p_psLineMin(psMinimization *min,
+                  psVector *params,
+                  psVector *line,
+                  const psVector *paramMask,
+                  const psArray *coords,
+                  psMinimizePowellFunc func)
+{
+    PS_PTR_CHECK_NULL(min, NAN);
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_EMPTY(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(line, NAN);
+    PS_VECTOR_CHECK_EMPTY(line, NAN);
+    PS_VECTOR_CHECK_TYPE(line, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(paramMask, NAN);
+    PS_VECTOR_CHECK_EMPTY(paramMask, NAN);
+    PS_VECTOR_CHECK_TYPE(paramMask, PS_TYPE_U8, NAN);
+    PS_PTR_CHECK_NULL(coords, NAN);
+    PS_PTR_CHECK_NULL(func, NAN);
+    psVector *bracket;
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 n = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psF32 fn = 0.0;
+    psF32 mul = 0.0;
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpa, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpb, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpc, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpn, params->n, PS_TYPE_F32);
+    psS32 i = 0;
+    psS32 boolLineIsNull = true;
+    psS32 numIterations = 0;
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4, "---- p_psLineMin() begin ----\n");
+    PS_VECTOR_F32_CHECK_ZERO_VECTOR(line, boolLineIsNull);
+
+    if (boolLineIsNull == true) {
+        min->value = func(params, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 2,
+                "p_psLineMin() called with zero line vector.  Return 0.0.  Function value is %f\n", min->value);
+        return(0.0);
+    }
+
+    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_psDetermineBracket2(params, line, paramMask, coords, func);
+    if (bracket == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not bracket minimum.  Returning NAN.\n");
+        return(NAN);
+    }
+    numIterations = 0;
+    while (numIterations < PS_LINEMIN_MAX_ITERATIONS) {
+        numIterations++;
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "p_psLineMin(): iteration %d\n", numIterations);
+
+        a = bracket->data.F32[0];
+        b = bracket->data.F32[1];
+        c = bracket->data.F32[2];
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpa, a);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpb, b);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpc, c);
+        fa = func(tmpa, coords);
+        fb = func(tmpb, coords);
+        fc = func(tmpc, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "LineMin: f(%f %f %f) is (%f %f %f)\n", 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,
+                "LineMin: new bracket is (%f %f %f)\n", 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)) {
+            PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, params, mul);
+            min->value = func(params, coords);
+            psFree(bracket);
+            psTrace(".psLib.dataManip.p_psLineMin", 4,
+                    "---- p_psLineMin() end.a (%f) (%f) ----\n", mul, min->value);
+            return(mul);
+        }
+    }
+
+    mul = bracket->data.F32[1];
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, params, mul);
+    min->value = func(params, coords);
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() end.b (%f) %f ----\n", mul, min->value);
+
+    psFree(bracket);
+    return(mul);
+}
+
+
+/******************************************************************************
+This routine must minimize a possibly multi-dimensional function.  The
+function to be minimized "func" is:
+    psF32 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: Check for F32 types?
+ *****************************************************************************/
+#define PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS 20
+#define PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE 0.01
+
+psBool psMinimizePowell(psMinimization *min,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *coords,
+                        psMinimizePowellFunc func)
+{
+    PS_PTR_CHECK_NULL(min, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(func, NULL);
+    psS32 numDims = params->n;
+    PS_VECTOR_GEN_STATIC_RECYCLED(pQP, numDims, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(u, numDims, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(Q, numDims, PS_TYPE_F32);
+    psS32 i = 0;
+    psS32 j = 0;
+    psVector *myParamMask = NULL;
+    psMinimization dummyMin;
+    psF32 mul = 0.0;
+    psF32 baseFuncVal = 0.0;
+    psF32 currFuncVal = 0.0;
+    psS32 biggestIter = 0;
+    psF32 biggestDiff = 0.0;
+    psS32 iterationNumber = 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);
+
+    if (paramMask == NULL) {
+        myParamMask = psVectorRecycle(myParamMask, params->n, PS_TYPE_U8);
+        p_psMemSetPersistent(myParamMask, true);
+        p_psMemSetPersistent(myParamMask->data.V, true);
+        for (i=0;i<myParamMask->n;i++) {
+            myParamMask->data.U8[i] = 0;
+        }
+    } else {
+        myParamMask = (psVector *) paramMask;
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(params, myParamMask, NULL);
+
+    // 1: Set v[i] to be the unit vectors for each dimension in params
+    psArray *v = psArrayAlloc(numDims);
+    for (i=0;i<numDims;i++) {
+        (v->data[i]) = (psVector *) psVectorAlloc(numDims, PS_TYPE_F32);
+        for (j=0;j<numDims;j++) {
+            if (i == j) {
+                ((psVector *) (v->data[i]))->data.F32[j] = 1.0;
+            } else {
+                ((psVector *) (v->data[i]))->data.F32[j] = 0.0;
+            }
+        }
+    }
+
+    // 2: Set Q to be the initial params (P in the ADD)
+    for (i=0;i<numDims;i++) {
+        Q->data.F32[i] = params->data.F32[i];
+    }
+
+    while (iterationNumber < min->maxIter) {
+        iterationNumber++;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "psMinimizePowell() iteration %d\n", iterationNumber);
+
+        // 3: For each dimension in params, move Q only in the vector v[i] to
+        //    minimize the function.
+
+        baseFuncVal = func(Q, coords);
+        currFuncVal = baseFuncVal;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "Current function value is %f\n", currFuncVal);
+
+        biggestDiff = 0;
+        biggestIter = 0;
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                dummyMin.maxIter = PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS;
+                dummyMin.tol = PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE;
+                mul = p_psLineMin(&dummyMin,
+                                  Q,
+                                  ((psVector *) v->data[i]),
+                                  myParamMask,
+                                  coords,
+                                  func);
+                if (isnan(mul)) {
+                    psError(PS_ERR_UNKNOWN, false,
+                            "Could not perform line minimization.  Returning FALSE.\n");
+                    psFree(v);
+                    return(false);
+                }
+                psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                        "LineMin along dimension %d has multiple %f\n", i, mul);
+
+                if (fabs(dummyMin.value - currFuncVal) > biggestDiff) {
+                    biggestDiff = fabs(dummyMin.value - currFuncVal);
+                    biggestIter = i;
+                }
+                currFuncVal = dummyMin.value;
+            }
+        }
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "New function value is %f\n", currFuncVal);
+
+        // 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[i]=Q[i]-P[i] (%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.
+        for (i=0;i<numDims;i++) {
+            psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                    "u[i] is %f\n", u->data.F32[i]);
+        }
+
+        mul = p_psLineMin(&dummyMin, params, u, myParamMask, coords, func);
+        if (isnan(mul)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not perform line minimization.  Returning FALSE.\n");
+            psFree(v);
+            return(false);
+        }
+
+        // 6:
+        if (dummyMin.value > currFuncVal) {
+            psFree(v);
+            min->iter = iterationNumber;
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (1)(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];
+            }
+        }
+        psF32 fqp = func(pQP, coords);
+        psF32 term1 = (baseFuncVal - currFuncVal) - biggestDiff;
+        term1*= term1;
+        term1*= 2.0 * (baseFuncVal - (2.0 * currFuncVal) + fqp);
+        psF32 term2 = baseFuncVal - fqp;
+        term2*= term2 * biggestDiff;
+        if (term1 < term2) {
+            for (i=0;i<numDims;i++) {
+                if (myParamMask->data.U8[i] == 0) {
+                    ((psVector *) v->data[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) {
+            psFree(v);
+            min->iter = iterationNumber;
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (2) (true) ----\n");
+            return(true);
+        }
+    }
+
+    psFree(v);
+    min->iter = iterationNumber;
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() end (0) (false) ----\n");
+    return(false);
+}
+
+
+/******************************************************************************
+XXX: We assume unnormalized gaussians.
+XXX: Currently, yErr is ignored.
+ *****************************************************************************/
+psVector *psMinimizePowellChi2Gauss1D(const psVector *params,
+                                      const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psF32 x;
+    psS32 i;
+    psF32 mean = params->data.F32[0];
+    psF32 stdev = params->data.F32[1];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        out->data.F32[i] = psGaussian(x, mean, stdev, false);
+    }
+
+    return(out);
+}
+
+/******************************************************************************
+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
+ *****************************************************************************/
+psF32 myPowellChi2Func(const psVector *params,
+                       const psArray *coords)
+{
+    psTrace(".psLib.dataManip.myPowellChi2Func", 4,
+            "---- myPowellChi2Func() begin ----\n");
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_EMPTY(params, NAN);
+    PS_VECTOR_CHECK_NULL(myValue, NAN);
+    PS_VECTOR_CHECK_EMPTY(myValue, NAN);
+    PS_PTR_CHECK_NULL(coords, NAN);
+
+    psF32 chi2 = 0.0;
+    psF32 d;
+    psS32 i;
+    psVector *tmp;
+
+    tmp = Chi2PowellFunc(params, coords);
+    if (myError == NULL) {
+        for (i=0;i<coords->n;i++) {
+            d = (tmp->data.F32[i] - myValue->data.F32[i]);
+            chi2+= d * d;
+        }
+    } else {
+        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);
+    psTrace(".psLib.dataManip.myPowellChi2Func", 4,
+            "---- myPowellChi2Func() end (chi2 is %f) ----\n", chi2);
+    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().
+ *****************************************************************************/
+psBool 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/rel4/psLib/src/dataManip/psMinimize.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psMinimize.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psMinimize.h	(revision 3057)
@@ -0,0 +1,126 @@
+/** @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.37 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-22 05:09:32 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PS_MINIMIZE_H)
+#define PS_MINIMIZE_H
+
+/** \file psMinimize.h
+ *  \brief minimization operations
+ *  \ingroup Stats
+ */
+/** \addtogroup Stats
+ *  \{
+ */
+
+#include "psVector.h"
+#include "psMemory.h"
+#include "psArray.h"
+#include "psImage.h"
+#include "psMatrix.h"
+#include "psFunctions.h"
+#include "psStats.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psConstants.h"
+
+typedef struct
+{
+    psS32 maxIter;                       ///< Convergence limit
+    psF32 tol;                         ///< Error Tolerance
+    psF32 value;                       ///< Value of function at minimum
+    psS32 iter;                          ///< Number of iterations required
+    psF32 lastDelta;                   ///< The last difference for the fit
+}
+psMinimization;
+
+psMinimization *psMinimizationAlloc(psS32 maxIter,
+                                    psF32 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
+                               );
+
+typedef
+psVector* (*psMinimizeLMChi2Func)(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *x);
+
+psBool psMinimizeLMChi2(psMinimization *min,
+                        psImage *covar,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *x,
+                        const psVector *y,
+                        const psVector *yErr,
+                        psMinimizeLMChi2Func func);
+
+typedef
+psF32 (*psMinimizePowellFunc)(const psVector *params,
+                              const psArray *coords);
+
+psBool psMinimizePowell(psMinimization *min,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *coords,
+                        psMinimizePowellFunc func);
+
+psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords);
+
+psVector *psMinimizePowellChi2Gauss1D(const psVector *params,
+                                      const psArray *coords);
+
+typedef
+psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,
+                                      const psArray *coords);
+
+psBool 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/rel4/psLib/src/dataManip/psRandom.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psRandom.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psRandom.c	(revision 3057)
@@ -0,0 +1,140 @@
+/** @file psRandom.c
+*  \brief Random Number Generators
+*  \ingroup Math
+*
+*  This file will hold the functions which allocate, free,
+*  and evaluate random number Generators.
+*
+*  @ingroup Math
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-15 01:15:09 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+#include <time.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include "psMemory.h"
+#include "psRandom.h"
+#include "psScalar.h"
+#include "psError.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+#include "psConstants.h"
+#include "psDataManipErrors.h"
+
+psU64 p_psRandomGetSystemSeed()
+{
+    FILE*  fd;
+    psU64  seedVal = 0;
+    time_t timeVal;
+
+    fd = fopen("/dev/urandom","r");
+    if(fd == NULL) {
+        // Read system clock to get seed
+        seedVal = (psU64)time(&timeVal);
+    } else {
+        // Read urandom to get seed
+        fread(&seedVal, sizeof(psU64),1,fd);
+        // Close file
+        fclose(fd);
+    }
+
+    // Send log message of the system seed value used
+    psLogMsg(__func__,PS_LOG_INFO,"System random seed value used  seed = %llX hex",seedVal);
+
+    return seedVal;
+}
+
+psRandom *psRandomAlloc(psRandomType type,
+                        psU64 seed)
+{
+    gsl_rng   *r      = NULL;
+    psRandom  *myRNG  = NULL;
+
+    switch (type) {
+    case PS_RANDOM_TAUS:
+        myRNG = (psRandom*)psAlloc(sizeof(psRandom));
+        r = gsl_rng_alloc(gsl_rng_taus);
+        myRNG->gsl = r;
+        if(seed == 0) {
+            gsl_rng_set(myRNG->gsl,p_psRandomGetSystemSeed());
+        }
+        break;
+
+    default:
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE);
+        break;
+    }
+    return(myRNG);
+}
+
+void psRandomReset(psRandom *rand,
+                   psU64 seed)
+{
+    // Check null psRandom
+    if(rand==NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+    } else {
+        // Check seed value to see if system seed should be used
+        if(seed == 0) {
+            gsl_rng_set(rand->gsl,p_psRandomGetSystemSeed());
+        } else {
+            gsl_rng_set(rand->gsl, seed);
+        }
+    }
+}
+
+psF64 psRandomUniform(const psRandom *r)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        return(gsl_rng_uniform(r->gsl));
+    }
+}
+
+psF64 psRandomGaussian(const psRandom *r)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        // XXX: What should sigma be?
+        return(gsl_ran_gaussian(r->gsl, 1.0));
+    }
+}
+
+psF64 psRandomPoisson(const psRandom *r, psF64 mean)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        return((psF64) gsl_ran_poisson(r->gsl, mean));
+    }
+}
+
Index: /branches/rel4/psLib/src/dataManip/psRandom.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psRandom.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psRandom.h	(revision 3057)
@@ -0,0 +1,59 @@
+/** @file psRandom.h
+*  \brief Random Number Generators
+*  \ingroup Math
+*
+*  This file will hold the prototypes for procedures which allocate, free,
+*  and evaluate random number Generators.
+*
+*  @ingroup Math
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-21 23:25:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#if !defined(PS_RANDOM_H)
+#define PS_RANDOM_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psVector.h"
+#include "psScalar.h"
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+/** \addtogroup Math
+ *  \{
+ */
+
+typedef enum {
+    PS_RANDOM_TAUS    ///< A maximally equidistributed combined Tausworthe generator.
+} psRandomType;
+
+typedef struct
+{
+    psRandomType type; ///< The type of RNG
+    gsl_rng *gsl; ///< The RNG itself
+}
+psRandom;
+
+psRandom *psRandomAlloc(psRandomType type,
+                        psU64 seed);
+
+void psRandomReset(psRandom *rand,
+                   psU64 seed);
+
+psF64 psRandomUniform(const psRandom *r);
+psF64 psRandomGaussian(const psRandom *r);
+psF64 psRandomPoisson(const psRandom *r, psF64 mean);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel4/psLib/src/dataManip/psStats.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psStats.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psStats.c	(revision 3057)
@@ -0,0 +1,2280 @@
+/** @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.110 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-14 23:27:56 $
+ *
+ *  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 "psLogMsg.h"
+#include "psError.h"
+#include "psStats.h"
+#include "psMinimize.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+#include "psDataManipErrors.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+#define PS_GAUSS_WIDTH 5       // The width of the Gaussian or boxcar smoothing.
+#define PS_CLIPPED_NUM_ITER_LB 1
+#define PS_CLIPPED_NUM_ITER_UB 10
+#define PS_CLIPPED_SIGMA_LB 1.0
+#define PS_CLIPPED_SIGMA_UB 10.0
+#define PS_POLY_MEDIAN_MAX_ITERATIONS 10
+
+#define PS_BIN_MIDPOINT(HISTOGRAM, BIN_NUM) \
+(0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM)+1]))
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+psVector* p_psConvertToF32(psVector* in);
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+psBool p_psGetStatValue(const psStats* stats, psF64 *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;
+    }
+}
+
+/******************************************************************************
+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().  Should we perform the sanity
+checks in each routine anyway?
+ 
+XXX: For many of these private stats routines, what should be done if there
+are no acceptable elements in the input vector (if no elements lie within
+range, or there are no unmasked elements, or the input vector is NULL)?
+Currently we set the value to NAN.
+ 
+XXX: Optimization: many routines have an "empty" boolean variable which keeps
+track of whether or not the vector has any valid elements.  This code can
+possibly be optimized away.
+ *****************************************************************************/
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.  If there was a problem with the mean calculation,
+this routine sets stats->sampleMean to NAN.
+ *****************************************************************************/
+psS32 p_psVectorSampleMean(const psVector* restrict myVector,
+                           const psVector* restrict errors,
+                           const psVector* restrict maskVector,
+                           psU32 maskVal,
+                           psStats* stats)
+{
+
+    psS32 i = 0;                // Loop index variable
+    psF32 mean = 0.0;           // The mean
+    psS32 count = 0;            // # of points in this mean
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (errors == NULL) {
+        if (stats->options & PS_STAT_USE_RANGE) {
+            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]) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    if ((stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+            }
+        } else {
+            if (maskVector != NULL) {
+                for (i = 0; i < myVector->n; i++) {
+                    if (!(maskVal & maskVector->data.U8[i])) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    mean += myVector->data.F32[i];
+                }
+                mean /= (psF32)myVector->n;
+            }
+        }
+    } else {
+        psF32 errorDivisor = 0.0;
+        if (stats->options & PS_STAT_USE_RANGE) {
+            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]) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    if ((stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+            }
+        } else {
+            if (maskVector != NULL) {
+                for (i = 0; i < myVector->n; i++) {
+                    if (!(maskVal & maskVector->data.U8[i])) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    mean += myVector->data.F32[i]/errors->data.F32[i];
+                    errorDivisor+= (1.0 / errors->data.F32[i]);
+                }
+                mean /= errorDivisor;
+            }
+        }
+    }
+
+    stats->sampleMean = mean;
+    if (isnan(mean)) {
+        return(-1);
+    } else {
+        return(0);
+    }
+
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.  If there was a problem with the max calculation,
+this routine sets stats->max to NAN.
+ *****************************************************************************/
+psS32 p_psVectorMax(const psVector* restrict myVector,
+                    const psVector* restrict maskVector,
+                    psU32 maskVal,
+                    psStats* stats)
+{
+    psS32 i = 0;                // Loop index variable
+    psF32 max = -PS_MAX_F32;    // The calculated maximum
+    psS32 empty = true;         // Does this vector have valid elements?
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        max = myVector->data.F32[i];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    max = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    } 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];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    }
+    if (empty == false) {
+        stats->max = max;
+    } else {
+        stats->max = NAN;
+        return(1);
+    }
+    return(0);
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.  If there was a problem with the min calculation,
+this routine sets stats->min to NAN.
+ *****************************************************************************/
+psS32 p_psVectorMin(const psVector* restrict myVector,
+                    const psVector* restrict maskVector,
+                    psU32 maskVal,
+                    psStats* stats)
+{
+    psS32 i = 0;                // Loop index variable
+    psF32 min = PS_MAX_F32;   // The calculated maximum
+    psS32 empty = true;         // Does this vector have valid elements?
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        min = myVector->data.F32[i];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    min = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    } 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];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    }
+
+    if (empty == false) {
+        stats->min = min;
+    } else {
+        stats->min = NAN;
+        return(1);
+    }
+    return(0);
+}
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): This routine returns
+"true" if the inputPsVector has 1 or more valid elements (a valid element is an
+unmasked element within the specified min/max range).  Otherwise, return
+"false".
+ *****************************************************************************/
+bool p_psVectorCheckNonEmpty(const psVector* restrict myVector,
+                             const psVector* restrict maskVector,
+                             psU32 maskVal,
+                             psStats* stats)
+{
+    PS_VECTOR_CHECK_NULL(myVector, -1);
+    PS_PTR_CHECK_NULL(stats, -1);
+    psS32 i = 0;                // Loop index variable
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    return(true);
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    return(true);
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    return(true);
+                }
+            }
+        } else {
+            if (myVector->n > 0) {
+                return(true);
+            }
+        }
+    }
+    return(false);
+}
+
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector that fall within the min/max
+range, if specified.
+ *****************************************************************************/
+psS32 p_psVectorNValues(const psVector* restrict myVector,
+                        const psVector* restrict maskVector,
+                        psU32 maskVal,
+                        psStats* stats)
+{
+    PS_VECTOR_CHECK_NULL(myVector, -1);
+    PS_PTR_CHECK_NULL(stats, -1);
+    psS32 i = 0;                // Loop index variable
+    psS32 numData = 0;          // The number of data points
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    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.  Returns true on success (including if there were
+no valid input vector elements).
+ 
+XXX: Use static vectors for sort arrays.
+ *****************************************************************************/
+bool p_psVectorSampleMedian(const psVector* restrict myVector,
+                            const psVector* restrict maskVector,
+                            psU32 maskVal,
+                            psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    psS32 i = 0;                        // Loop index variable
+    psS32 count = 0;
+    psS32 nValues = 0;
+
+    // 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);
+
+    // XXX: Is a warning message appropriate?  What value should we set the
+    // sampleMedian to?  Should we generate an error?
+    if (nValues <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleMedian(): no valid elements in input vector.\n");
+        return(true);
+        stats->sampleMedian = NAN;
+    }
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        // 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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count] = myVector->data.F32[i];
+                    count++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count] = myVector->data.F32[i];
+                    count++;
+                }
+            }
+        }
+    } 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];
+                    count++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    sortedVector = psVectorSort(sortedVector, unsortedVector);
+    if (sortedVector == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
+        return(false);
+    }
+
+    // Calculate the median exactly.  Use the average if the number of samples
+    // is even.
+    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);
+
+    // Return "true" on success.
+    return(true);
+}
+
+/******************************************************************************
+p_psVectorSmoothHistGaussian(): This routine smoothes the data in the input
+robustHistogram with a Gaussian of width sigma.
+ 
+XXX: Only PS_TYPE_F32 is supported.
+ 
+XXX: Write a general routine which smoothes a psVector.  This routine should
+call that.  Is that possible?
+ *****************************************************************************/
+psVector* p_psVectorSmoothHistGaussian(psHistogram* robustHistogram,
+                                       psF32 sigma)
+{
+    PS_PTR_CHECK_NULL(robustHistogram, NULL);
+    PS_PTR_CHECK_NULL(robustHistogram->bounds, NULL);
+
+    psS32 i = 0;                  // Loop index variable
+    psS32 j = 0;                  // Loop index variable
+    psF32 iMid;
+    psF32 jMid;
+    psS32 numBins = robustHistogram->nums->n;
+    psS32 numBounds = robustHistogram->bounds->n;
+    psVector* smooth = psVectorAlloc(numBins, PS_TYPE_F32);
+    psS32 jMin = 0;
+    psS32 jMax = 0;
+    psF32 firstBound = robustHistogram->bounds->data.F32[0];
+    psF32 lastBound = robustHistogram->bounds->data.F32[numBounds-1];
+    psScalar x;
+
+    x.type.type = PS_TYPE_F32;
+    for (i = 0; i < numBins; i++) {
+        // Determine the midpoint of bin i.
+        iMid = (robustHistogram->bounds->data.F32[i] +
+                robustHistogram->bounds->data.F32[i+1]) / 2.0;
+
+
+        // We determine the bin numbers corresponding to a range of data
+        // values surrounding iMid.  The ranges is of size
+        // s*PS_GAUSS_WIDTH*sigma
+
+        // YYY: The p_psVectorBinDisect() routine does much of the work of
+        // the following conditionals, however, it also reports a warning
+        // message.  I don't want the warning message so I reproduce the
+        // conditionals here.  Maybe p_psVectorBinDisect() should not produce
+        // warnings?
+
+        x.data.F32 = iMid - (PS_GAUSS_WIDTH * sigma);
+        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
+            jMin = p_psVectorBinDisect(robustHistogram->bounds, &x);
+            if (jMin < 0) {
+                psError(PS_ERR_UNEXPECTED_NULL,
+                        false,
+                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
+                return(NULL);
+            }
+        } else if (x.data.F32 <= firstBound) {
+            jMin = 0;
+        } else if (x.data.F32 >= lastBound) {
+            jMin = robustHistogram->bounds->n - 1;
+        }
+
+        x.data.F32 = iMid + (PS_GAUSS_WIDTH * sigma);
+        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
+            jMax = p_psVectorBinDisect(robustHistogram->bounds, &x);
+            if (jMax < 0) {
+                psError(PS_ERR_UNEXPECTED_NULL,
+                        false,
+                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
+                return(NULL);
+            }
+        } else if (x.data.F32 <= firstBound) {
+            jMax = 0;
+        } else if (x.data.F32 >= lastBound) {
+            jMax = robustHistogram->bounds->n - 1;
+        }
+
+        smooth->data.F32[i] = 0.0;
+        for (j = jMin ; j <= jMax ; j++) {
+            jMid = (robustHistogram->bounds->data.F32[j] +
+                    robustHistogram->bounds->data.F32[j+1]) / 2.0;
+            smooth->data.F32[i] +=
+                robustHistogram->nums->data.F32[j] *
+                psGaussian(jMid, iMid, sigma, true);
+        }
+    }
+
+    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
+ *****************************************************************************/
+bool p_psVectorSampleQuartiles(const psVector* restrict myVector,
+                               const psVector* restrict maskVector,
+                               psU32 maskVal,
+                               psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    psS32 i = 0;                  // Loop index variable
+    psS32 count = 0;              // # of points in this mean.
+    psS32 nValues = 0;            // # data points
+
+    // 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);
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        // 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]) &&
+                        (stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
+                    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.
+    sortedVector = psVectorSort(sortedVector, unsortedVector);
+    if (sortedVector == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
+        return(false);
+    }
+
+    // Calculate the quartile points exactly.
+    // XXX: We should probably do a bin-midpoint if the quartile is not an
+    // integer.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+    return(true);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+ *****************************************************************************/
+void p_psVectorSampleStdevOLD(const psVector* restrict myVector,
+                              const psVector* restrict errors,
+                              const psVector* restrict maskVector,
+                              psU32 maskVal,
+                              psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 countInt = 0;           // # of data points being used
+    psF32 countFloat = 0.0;     // # of data points being used
+    psF32 mean = 0.0;           // The mean
+    psF32 diff = 0.0;           // Used in calculating stdev
+    psF32 sumSquares = 0.0;     // temporary variable
+    psF32 sumDiffs = 0.0;       // temporary variable
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
+    }
+    // If the mean is NAN, then generate a warning and set the stdev to NAN.
+    if (0 != isnan(stats->sampleMean)) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
+        return;
+    }
+
+    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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    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;
+        }
+    }
+    if (countInt == 0) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d).  Setting stats->sampleStdev = NAN.\n", countInt);
+    } else if (countInt == 1) {
+        stats->sampleStdev = 0.0;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d).  Setting stats->sampleStdev = 0.0.\n", countInt);
+    } else {
+        countFloat = (psF32)countInt;
+        stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    }
+}
+/******************************************************************************
+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 errors,
+                           const psVector* restrict maskVector,
+                           psU32 maskVal,
+                           psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 countInt = 0;           // # of data points being used
+    psF32 countFloat = 0.0;     // # of data points being used
+    psF32 mean = 0.0;           // The mean
+    psF32 diff = 0.0;           // Used in calculating stdev
+    psF32 sumSquares = 0.0;     // temporary variable
+    psF32 sumDiffs = 0.0;       // temporary variable
+    //    psF32 sum1;
+    //    psF32 sum2;
+    psF32 errorDivisor;
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
+    }
+    // If the mean is NAN, then generate a warning and set the stdev to NAN.
+    if (0 != isnan(stats->sampleMean)) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
+        return;
+    }
+
+    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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+            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++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares += (diff * diff);
+                sumDiffs += diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+            if (errors != NULL) {
+                errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+            }
+        }
+    }
+
+    if (countInt == 0) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d).  Setting stats->sampleStdev = NAN.\n", countInt);
+    } else if (countInt == 1) {
+        stats->sampleStdev = 0.0;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d).  Setting stats->sampleStdev = 0.0.\n", countInt);
+    } else {
+        // XXX: The ADD specifies this as the definition of the standard
+        // deviation if the errors are known.  Verify this with IfA: none of
+        // the data points in the vector are used.  Verify that the masks and
+        // data ranges are used correctly.
+        if (errors != NULL) {
+            stats->sampleStdev = (1.0 / PS_SQRT_F32(errorDivisor));
+        } else {
+            countFloat = (psF32)countInt;
+            stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+        }
+    }
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, errors, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    0 for success.
+    -1: error
+    -2: warning
+ *****************************************************************************/
+psS32 p_psVectorClippedStats(const psVector* restrict myVector,
+                             const psVector* restrict errors,
+                             const psVector* restrict maskVector,
+                             psU32 maskVal,
+                             psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 j = 0;                  // Loop index variable
+    psF32 clippedMean = 0.0;    // self-explanatory
+    psF32 clippedStdev = 0.0;   // self-explanatory
+    psF32 oldStanMean = 0.0;    // Temporary variable
+    psF32 oldStanStdev = 0.0;   // Temporary variable
+    psVector* tmpMask = NULL;   // Temporary vector
+
+    // Ensure that stats->clipIter is within the proper range.
+    PS_INT_CHECK_RANGE(stats->clipIter,
+                       PS_CLIPPED_NUM_ITER_LB,
+                       PS_CLIPPED_NUM_ITER_UB, -1);
+
+    // Ensure that stats->clipSigma is within the proper range.
+    PS_INT_CHECK_RANGE(stats->clipSigma,
+                       PS_CLIPPED_SIGMA_LB,
+                       PS_CLIPPED_SIGMA_UB, -1);
+
+    // 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);
+
+    // 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.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+    if (isnan(stats->sampleMedian)) {
+        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleMedian returned NAN\n");
+        stats->clippedMean = NAN;
+        stats->clippedStdev = NAN;
+        return(-2);
+    }
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, errors, maskVector, maskVal, stats);
+    if (isnan(stats->sampleStdev)) {
+        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleStdev returned NAN\n");
+        stats->clippedMean = NAN;
+        stats->clippedStdev = NAN;
+        return(-2);
+    }
+
+    // 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++) {
+        // a) Exclude all values x_i for which |x_i - x| > K * stdev
+        if (errors != NULL) {
+            for (j = 0; j < myVector->n; j++) {
+                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * errors->data.F32[j])) {
+                    tmpMask->data.U8[i] = 0xff;
+                }
+            }
+        } else {
+            for (j = 0; j < myVector->n; j++) {
+                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
+                    tmpMask->data.U8[i] = 0xff;
+                }
+            }
+        }
+
+        // b) compute new mean and stdev
+        p_psVectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
+        p_psVectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
+
+        // If the new mean and stdev are not NAN, then we use them.
+        // Otherwise, keep the old ones, and exit the loop.
+        if (! (isnan(stats->sampleMean) || isnan(stats->sampleStdev))) {
+            clippedMean = stats->sampleMean;
+            clippedStdev = stats->sampleStdev;
+
+            // Exit loop
+            i = stats->clipIter;
+        }
+    }
+
+    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);
+    return(0);
+}
+
+/*****************************************************************************
+These macros and functions define the following functions:
+ 
+    p_psNormalizeVectorRange(myData, low, high)
+ 
+That assumes that the low/high arguments are PS_TYPE_F64; the vector myData
+can be of any type.  Arguments low/high will be converted to the appropriate
+type and one of the type-specific functions below will be called:
+ 
+    p_psNormalizeVectorRangeU8(myData, low, high)
+    p_psNormalizeVectorRangeU16(myData, low, high)
+    p_psNormalizeVectorRangeU32(myData, low, high)
+    p_psNormalizeVectorRangeU64(myData, low, high)
+    p_psNormalizeVectorRangeS8(myData, low, high)
+    p_psNormalizeVectorRangeS16(myData, low, high)
+    p_psNormalizeVectorRangeS32(myData, low, high)
+    p_psNormalizeVectorRangeS64(myData, low, high)
+    p_psNormalizeVectorRangeF32(myData, low, high)
+    p_psNormalizeVectorRangeF64(myData, low, high)
+ *****************************************************************************/
+#define PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(TYPE) \
+void p_psNormalizeVectorRange##TYPE(psVector* myData, \
+                                    ps##TYPE outLow, \
+                                    ps##TYPE outHigh) \
+{ \
+    ps##TYPE min = (ps##TYPE) PS_MAX_##TYPE; \
+    ps##TYPE max = (ps##TYPE) -PS_MAX_##TYPE; \
+    psS32 i = 0; \
+    \
+    for (i = 0; i < myData->n; i++) { \
+        if (myData->data.TYPE[i] < min) { \
+            min = myData->data.TYPE[i]; \
+        } \
+        if (myData->data.TYPE[i] > max) { \
+            max = myData->data.TYPE[i]; \
+        } \
+    } \
+    \
+    /* Ensure that max!=min before we divide by (max-min) */ \
+    if (max != min) { \
+        for (i = 0; i < myData->n; i++) { \
+            myData->data.TYPE[i] = (outLow + (myData->data.TYPE[i] - min) * \
+                                    (outHigh - outLow) / (max - min)); \
+        } \
+    } else { \
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: (max==min).  Setting all elements to min.\n"); \
+        for (i = 0; i < myData->n; i++) \
+        { \
+            \
+            myData->data.TYPE[i] = outLow; \
+            \
+        } \
+    } \
+} \
+
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U8)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U16)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U64)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S8)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S16)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S64)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F64)
+
+void p_psNormalizeVectorRange(psVector* myData,
+                              psF64 outLow,
+                              psF64 outHigh)
+{
+    switch (myData->type.type) {
+    case PS_TYPE_U8:
+        p_psNormalizeVectorRangeU8(myData, (psU8) outLow, (psU8) outHigh);
+        break;
+    case PS_TYPE_U16:
+        p_psNormalizeVectorRangeU16(myData, (psU16) outLow, (psU16) outHigh);
+        break;
+    case PS_TYPE_U32:
+        p_psNormalizeVectorRangeU32(myData, (psU32) outLow, (psU32) outHigh);
+        break;
+    case PS_TYPE_U64:
+        p_psNormalizeVectorRangeU64(myData, (psU64) outLow, (psU64) outHigh);
+        break;
+    case PS_TYPE_S8:
+        p_psNormalizeVectorRangeS8(myData, (psS8) outLow, (psS8) outHigh);
+        break;
+    case PS_TYPE_S16:
+        p_psNormalizeVectorRangeS16(myData, (psS16) outLow, (psS16) outHigh);
+        break;
+    case PS_TYPE_S32:
+        p_psNormalizeVectorRangeS32(myData, (psS32) outLow, (psS32) outHigh);
+        break;
+    case PS_TYPE_S64:
+        p_psNormalizeVectorRangeS64(myData, (psS64) outLow, (psS64) outHigh);
+        break;
+    case PS_TYPE_F32:
+        p_psNormalizeVectorRangeF32(myData, (psF32) outLow, (psF32) outHigh);
+        break;
+    case PS_TYPE_F64:
+        p_psNormalizeVectorRangeF64(myData, (psF64) outLow, (psF64) outHigh);
+        break;
+    case PS_TYPE_C32:
+    case PS_TYPE_C64:
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                "Unallowable operation: %s has incorrect type.",
+                myData);
+        break;
+    }
+}
+
+/******************************************************************************
+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.
+ 
+XXX: Create a 2nd-order polynomial version and solve for X analytically.
+ *****************************************************************************/
+psF32 p_ps1DPolyMedian(psPolynomial1D* myPoly,
+                       psF32 rangeLow,
+                       psF32 rangeHigh,
+                       psF32 getThisValue)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+    PS_FLOAT_COMPARE(rangeLow, rangeHigh, NAN);
+    // We ensure that the requested f(y) value, which is getThisValue, is
+    // falls within the range of y-values of the polynomial "myPoly" in the
+    // specified x-range (rangeLow:rangeHigh).
+    psF32 fLo = psPolynomial1DEval(
+                    myPoly,
+                    rangeLow
+                );
+    psF32 fHi = psPolynomial1DEval(
+                    myPoly,
+                    rangeHigh
+                );
+    if (!((fLo <= getThisValue) && (fHi >= getThisValue))) {
+        psError(PS_ERR_UNKNOWN,
+                true,
+                PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE);
+        return(NAN);
+    }
+
+    psS32 numIterations = 0;
+    psF32 midpoint = 0.0;
+    psF32 oldMidpoint = 1.0;
+    psF32 f = 0.0;
+
+    while (numIterations < PS_POLY_MEDIAN_MAX_ITERATIONS) {
+        midpoint = (rangeHigh + rangeLow) / 2.0;
+        if (fabs(midpoint - oldMidpoint) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+        oldMidpoint = midpoint;
+
+        f = psPolynomial1DEval(
+                myPoly,
+                midpoint
+            );
+        if (fabs(f - getThisValue) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+
+        if (f > getThisValue) {
+            rangeHigh = midpoint;
+        } else {
+            rangeLow = midpoint;
+        }
+        numIterations++;
+    }
+    return (midpoint);
+}
+
+/******************************************************************************
+fitQuadraticSearchForYThenReturnX(*xVec, *yVec, binNum, yVal): A general
+routine which fits a quadratic to three points and returns the x-value
+corresponding to the input y-value.  This routine takes psVectors of x/y pairs
+as input, and fits a quadratic to the 3 points surrounding element binNum in
+the vectors (the midpoint between element i and i+1 is used for x[i]).  It
+then determines for what value x does that quadratic f(x) = yVal (the input
+parameter).
+ 
+XXX: After you fit the polynomial, solve for X analytically.
+ 
+XXX: the vectors do not have to be the same length.  Must insert the proper
+tests to ensure that binNum is within acceptable ranges for both vectors.
+*****************************************************************************/
+psF32 fitQuadraticSearchForYThenReturnX(psVector *xVec,
+                                        psVector *yVec,
+                                        psS32 binNum,
+                                        psF32 yVal)
+{
+    PS_VECTOR_CHECK_NULL(xVec, NAN);
+    PS_VECTOR_CHECK_NULL(yVec, NAN);
+    PS_VECTOR_CHECK_TYPE(xVec, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_TYPE(yVec, PS_TYPE_F32, NAN);
+    //    PS_VECTOR_CHECK_SIZE_EQUAL(xVec, yVec, NAN);
+    PS_INT_CHECK_RANGE(binNum, 0, (xVec->n - 1), NAN);
+    PS_INT_CHECK_RANGE(binNum, 0, (yVec->n - 1), NAN);
+
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(x, 3, PS_TYPE_F64);
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(y, 3, PS_TYPE_F64);
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(yErr, 3, PS_TYPE_F64);
+    //    PS_POLY_1D_DECLARE_ALLOC_STATIC(myPoly, 2, PS_POLYNOMIAL_ORD);
+    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);
+
+    psF32 tmpFloat;
+
+    if ((binNum > 0) && (binNum < (yVec->n - 2))) {
+        // The general case.  We have all three points.
+        x->data.F64[0] = (psF64) (0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
+        x->data.F64[1] = (psF64) (0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum+1]));
+        x->data.F64[2] = (psF64) (0.5 * (xVec->data.F32[binNum+1] + xVec->data.F32[binNum+2]));
+        y->data.F64[0] = yVec->data.F32[binNum - 1];
+        y->data.F64[1] = yVec->data.F32[binNum];
+        y->data.F64[2] = yVec->data.F32[binNum + 1];
+
+        // Ensure that yVal is within the range of the bins we are using.
+        if (!((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2]))) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE,
+                    (psF64)yVal,y->data.F64[2],y->data.F64[0]);
+        }
+        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);
+        if (myPoly == NULL) {
+            psError(PS_ERR_UNEXPECTED_NULL,
+                    false,
+                    PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT);
+            psFree(myPoly);
+            psFree(x);
+            psFree(y);
+            psFree(yErr);
+            return(NAN);
+        }
+        // Call p_ps1DPolyMedian(), which does a binary search on the
+        // polynomial, looking for the value x such that f(x) = yVal
+        tmpFloat = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], yVal);
+        if (isnan(tmpFloat)) {
+            psError(PS_ERR_UNEXPECTED_NULL,
+                    false,
+                    PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN);
+            psFree(myPoly);
+            psFree(x);
+            psFree(y);
+            psFree(yErr);
+            return(NAN);
+        }
+
+    } else {
+        // The special case where we have two points only at the beginning of
+        // the vectors x and y.
+        if (binNum == 0) {
+            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
+                              xVec->data.F32[binNum + 1]);
+        } else if (binNum == (xVec->n - 1)) {
+            // The special case where we have two points only at the end of
+            // the vectors x and y.
+            // XXX: Is this right?
+            tmpFloat = xVec->data.F32[binNum];
+        } else if (binNum == (xVec->n - 2)) {
+            // XXX: Is this right?
+            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
+                              xVec->data.F32[binNum + 1]);
+        }
+    }
+
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    return(tmpFloat);
+}
+
+/******************************************************************************
+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.).
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    0 on success.
+ 
+XXX: Check for errors in psLib routines that we call.
+*****************************************************************************/
+psS32 p_psVectorRobustStats(const psVector* restrict myVector,
+                            const psVector* restrict errors,
+                            const psVector* restrict maskVector,
+                            psU32 maskVal,
+                            psStats* stats)
+{
+    psHistogram* robustHistogram = NULL;
+    psVector* robustHistogramVector = NULL;
+    psF32 binSize = 0.0;        // Size of the histogram bins
+    psS32 LQBinNum = -1;          // Bin num for lower quartile
+    psS32 UQBinNum = -1;          // Bin num for upper quartile
+    psS32 medianBinNum = -1;
+    psS32 i = 0;                  // Loop index variable
+    psS32 modeBinNum = 0;
+    psF32 modeBinCount = 0.0;
+    psF32 dL = 0.0;
+    psS32 numBins = 0;
+    psF32 myMean = 0.0;
+    psF32 myStdev = 0.0;
+    psF32 countFloat = 0.0;
+    psF32 diff = 0.0;
+    psF32 sumSquares = 0.0;
+    psF32 sumDiffs = 0.0;
+    psVector* cumulativeRobustSums = NULL;
+    psF32 sumRobust = 0.0;
+    psF32 sumN50 = 0.0;
+    psF32 sumNfit = 0.0;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+    psStats* tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV | PS_STAT_CLIPPED_MEAN);
+
+    // 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;
+    //XXX: add errors
+    psS32 rc = p_psVectorClippedStats(myVector, NULL, maskVector, maskVal, tmpStats);
+    if (rc != 0) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS);
+        return(1);
+    }
+    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(0);
+    }
+
+    // Determine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        if (0 != p_psVectorMin(myVector, maskVector, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: p_psVectorMin(): p_psVectorMin() reported a NAN mean.\n");
+            return(1);
+        }
+    }
+    if (isnan(stats->max)) {
+        if (0 != p_psVectorMax(myVector, maskVector, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: p_psVectorMin(): p_psVectorMax() reported a NAN mean.\n");
+            return(1);
+        }
+    }
+
+    // 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 = (psS32)((stats->max - stats->min) / binSize);
+    robustHistogram = psHistogramAlloc(stats->min, stats->max, numBins);
+
+    // Populate the histogram array.
+    psVectorHistogram(robustHistogram, myVector, errors, maskVector, maskVal);
+
+    // Smooth the histogram, Gaussian-style.
+    robustHistogramVector = p_psVectorSmoothHistGaussian(robustHistogram,
+                            tmpStats->clippedStdev / 4.0f);
+
+    /**************************************************************************
+    Determine the median/lower/upper quartile bin numbers.
+
+    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 in
+    determining the median and lower/upper quartiles.
+    **************************************************************************/
+    cumulativeRobustSums = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    cumulativeRobustSums->data.F32[0] = robustHistogramVector->data.F32[0];
+    for (i = 1; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSums->data.F32[i] = cumulativeRobustSums->data.F32[i - 1] +
+                                            robustHistogramVector->data.F32[i];
+    }
+    sumRobust = cumulativeRobustSums->data.F32[robustHistogramVector->n - 1];
+
+    tmpScalar.data.F32 = sumRobust / 4.0;
+    LQBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+    tmpScalar.data.F32 = 3.0 * sumRobust / 4.0;
+    UQBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+    tmpScalar.data.F32 = sumRobust / 2.0;
+    medianBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+
+    if ((LQBinNum < 0) || (UQBinNum < 0)) {
+        psError(PS_ERR_UNKNOWN, true,
+                PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED);
+        return(1);
+    }
+    if (medianBinNum < 0) {
+        psError(PS_ERR_UNKNOWN, true,
+                PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED);
+        return(1);
+    }
+    /**************************************************************************
+    Determine the mode in the range LQ:UQ.
+    **************************************************************************/
+    // Determine the bin with the peak value in the range LQ to UQ.
+    modeBinNum = LQBinNum;
+    modeBinCount = robustHistogramVector->data.F32[LQBinNum];
+    sumN50 = robustHistogram->nums->data.F32[LQBinNum];
+    for (i = LQBinNum + 1; i <= UQBinNum; i++) {
+        if (robustHistogramVector->data.F32[i] > modeBinCount) {
+            modeBinNum = i;
+            modeBinCount = robustHistogramVector->data.F32[i];
+        }
+        sumN50 += robustHistogram->nums->data.F32[i];
+    }
+
+    dL = (UQBinNum - LQBinNum) / 4;
+    /**************************************************************************
+    Determine the mean/stdev for the bins in the range mode-dL to mode+dL
+    **************************************************************************/
+    // 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).
+    sumNfit = 0.0;
+    myMean = 0.0;
+    for (i = modeBinNum - dL; i <= modeBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            myMean += (robustHistogramVector->data.F32[i]) * PS_BIN_MIDPOINT(robustHistogram, i);
+            countFloat += robustHistogramVector->data.F32[i];
+        }
+
+        sumNfit += robustHistogram->nums->data.F32[i];
+    }
+    // XXX: divide by zero?
+    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 = modeBinNum - dL; i <= modeBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            diff = PS_BIN_MIDPOINT(robustHistogram, i) - myMean;
+            sumSquares += diff * diff * robustHistogramVector->data.F32[i];
+            sumDiffs += diff * robustHistogramVector->data.F32[i];
+        }
+    }
+    myStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+    // Using the above (myMean, myStdev) as initial estimates, we fit a
+    // Gaussian to the robustHistogramVector.
+    psMinimization *min = psMinimizationAlloc(100, 0.1);
+    psVector *myParams = psVectorAlloc(2, PS_TYPE_F32);
+    psArray *myCoords = psArrayAlloc(robustHistogramVector->n);
+    psVector *y = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+
+    p_psNormalizeVectorRangeF32(robustHistogramVector, 0.0, 1.0);
+    for (i=0;i<robustHistogramVector->n;i++) {
+        myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (psF32) i;
+        y->data.F32[i] = robustHistogramVector->data.F32[i];
+    }
+
+    myParams->data.F32[0] = myMean;
+    myParams->data.F32[1] = myStdev;
+    psImage *covar = NULL;
+    psMinimizeLMChi2(min,
+                     NULL,
+                     myParams,
+                     NULL,
+                     myCoords,
+                     y,
+                     NULL,
+                     (psMinimizeLMChi2Func) psMinimizeLMChi2Gauss1D);
+    psFree(covar);
+    psFree(min);
+    psFree(myParams);
+    psFree(myCoords);
+    psFree(y);
+    /**************************************************************************
+    Set the appropriate members in the output stats struct.
+    **************************************************************************/
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        if (fabs((myParams->data.F32[0] - myMean)/myMean) > 0.1) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the fitted Gaussian has more than 10%% error for the mean.\n");
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: Using the calculated mean instead of Gaussian-fitted mean.");
+            //                     "WARNING: Using the calculated mean instead of Gaussian-fitted mean.(calc, fit) is (%f, %f)\n",
+            //                     myMean, myParams->data.F32[0]);
+            stats->robustMean = myMean;
+        } else {
+            stats->robustMean = myParams->data.F32[0];
+        }
+    }
+
+    if (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = PS_BIN_MIDPOINT(robustHistogram, modeBinNum);
+    }
+
+    if (stats->options & PS_STAT_ROBUST_STDEV) {
+        if (fabs((myParams->data.F32[1] - myStdev)/myStdev) > 0.1) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the fitted Gaussian has more than 10%% error for the stdev.\n");
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: Using the calculated stdev instead of Gaussian-fitted stdev.");
+            //                     "WARNING: Using the calculated stdev instead of Gaussian-fitted stdev.(calc, fit) is (%f, %f)\n",
+            //                     myStdev, myParams->data.F32[1]);
+            stats->robustStdev = myStdev;
+        } else {
+            stats->robustStdev = myParams->data.F32[1];
+        }
+    }
+
+    // To determine the median, we fit a quadratic y=f(x) to the three bins
+    // surrounding the bin containing the median (x is the midpoint of each
+    // bin and y is the value of each bin).  Then we figure out what value
+    // of x corresponds to f(x) being the median (half of all points).
+    if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        // Take a psVector.  Fit a polynomial y = f(x) to the 3 data elements
+        // surrounding medianBinNum, then find the x-value corresponding y = sumRobust/2.0.
+
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustMedian = fitQuadraticSearchForYThenReturnX(
+                                  robustHistogram->bounds,
+                                  cumulativeRobustSums,
+                                  medianBinNum,
+                                  sumRobust/2.0);
+    }
+
+    // To determine the quartiles, we fit a quadratic y=f(x) to the three bins
+    // surrounding the bin containing LQ/UQ (x is the midpoint of each
+    // bin and y is the value of each bin).  Then we figure out what value
+    // of x corresponds to f(x) being the LQ/UQ.
+    if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        countFloat = cumulativeRobustSums->data.F32[robustHistogramVector->n - 1];
+
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustLQ = fitQuadraticSearchForYThenReturnX(
+                              robustHistogram->bounds,
+                              cumulativeRobustSums,
+                              LQBinNum,
+                              countFloat/4.0);
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustUQ = fitQuadraticSearchForYThenReturnX(
+                              robustHistogram->bounds,
+                              cumulativeRobustSums,
+                              UQBinNum,
+                              3.0 * countFloat/4.0);
+    }
+    // XXX: I think sumNfit == sumN50 here.
+    stats->robustNfit = sumNfit;
+    stats->robustN50 = sumN50;
+
+    psFree(tmpStats);
+    psFree(robustHistogram);
+    psFree(robustHistogramVector);
+    psFree(cumulativeRobustSums);
+    return(0);
+}
+
+/*****************************************************************************/
+
+/* 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(psF32 lower, psF32 upper, psS32 n)
+{
+    PS_INT_CHECK_POSITIVE(n, NULL);
+    PS_FLOAT_COMPARE(lower, upper, NULL);
+
+    psS32 i = 0;                  // Loop index variable
+    psHistogram* newHist = NULL;        // The new histogram structure
+    psF32 binSize = 0.0;        // The histogram bin size
+
+    // 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) / (psF32)n;
+    // XXX: 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 * (psF32)i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums = psVectorAlloc(n, PS_TYPE_F32);
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.F32[i] = 0.0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return (newHist);
+}
+
+/******************************************************************************
+psHistogramAllocGeneric(bounds): allocate a non-uniform histogram structure
+with the specifed bounds.
+ 
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAllocGeneric(const psVector* restrict bounds)
+{
+    PS_VECTOR_CHECK_NULL(bounds, NULL);
+    PS_VECTOR_CHECK_TYPE(bounds, PS_TYPE_F32, NULL);
+    PS_INT_COMPARE(2, bounds->n, NULL);
+
+    psHistogram* newHist = NULL;        // The new histogram structure
+    psS32 i;                      // Loop index variable
+
+    // 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_F32);
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.F32[i] = 0.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);
+}
+
+/*****************************************************************************
+UpdateHistogramBins(binNum, out, data, error): This routine is to be used when
+updating the histogram in the presence of errors in the input data.  We treat
+the data point as a boxcar PDF and update a range of points surrounding the
+histogram bin which contains the point.  The width of that boxcar is defined
+as 2.35 * error.  Inputs:
+    binNum: the bin number of the data point in the histogram
+    out: the histogram structure
+    data: the data point value
+    error: the error in that data point
+ 
+XXX: Must test this.
+ *****************************************************************************/
+psS32 UpdateHistogramBins(psS32 binNum,
+                          psHistogram* out,
+                          psF32 data,
+                          psF32 error)
+{
+    PS_PTR_CHECK_NULL(out, -1);
+    PS_PTR_CHECK_NULL(out->bounds, -1);
+    PS_PTR_CHECK_NULL(out->nums, -1);
+    PS_INT_CHECK_RANGE(binNum, 0, ((out->nums->n)-1), -2);
+    PS_FLOAT_COMPARE(0.0, error, -3);
+    PS_FLOAT_CHECK_RANGE(data, out->bounds->data.F32[0], out->bounds->data.F32[(out->bounds->n)-1], -4);
+
+    psF32 boxcarWidth = 2.35 * error;
+    psF32 boxcarCenter = (out->bounds->data.F32[binNum] +
+                          out->bounds->data.F32[binNum+1]) / 2.0;
+    psF32 boxcarLeft = boxcarCenter - (boxcarWidth / 2.0);
+    psF32 boxcarRight = boxcarCenter + (boxcarWidth / 2.0);
+    psS32 bin;
+    psS32 boxcarLeftBinNum;
+    psS32 boxcarRightBinNum;
+
+    // Determine the left endpoint of the boxcar for the PDF.
+    for (bin=binNum ; bin >= 0 ; bin--) {
+        if (out->nums->data.F32[bin] <= boxcarLeft) {
+            boxcarLeftBinNum = bin;
+            break;
+        }
+    }
+
+    // Determine the right endpoint of the boxcar for the PDF.
+    for (bin=binNum ; bin < out->nums->n ; bin++) {
+        if (out->nums->data.F32[bin] >= boxcarRight) {
+            boxcarRightBinNum = bin;
+            break;
+        }
+    }
+
+    //
+    // If the boxcar fits entirely inside this bin, then simply add 1.0 to the
+    // bin and return.
+    //
+    if (boxcarLeftBinNum == boxcarRightBinNum) {
+        out->nums->data.F32[binNum]+= 1.0;
+        return(0);
+    }
+
+    //
+    // If we get here, multiple bins must be updated.  We handle the left
+    // endpoint, and right endpoint differently.
+    //
+    out->nums->data.F32[boxcarLeftBinNum]+=
+        (out->bounds->data.F32[boxcarLeftBinNum+1] - boxcarLeft) / boxcarWidth;
+
+    //
+    // Loop through the center bins, if any.
+    //
+    for (bin = boxcarLeftBinNum + 1 ; bin < (boxcarRightBinNum - 1) ; bin++) {
+        out->nums->data.F32[bin]+=
+            (out->bounds->data.F32[bin+1] - out->bounds->data.F32[bin]) / boxcarWidth;
+    }
+
+    //
+    // Handle the right endpoint differently.
+    //
+    out->nums->data.F32[boxcarRightBinNum]+=
+        (boxcarRight - out->bounds->data.F32[boxcarRightBinNum]) / boxcarWidth;
+
+    //
+    // Return 0 on success.
+    //
+    return(0);
+}
+
+
+/*****************************************************************************
+psVectorHistogram(out, in, errors, 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 errors,
+                               const psVector* restrict mask,
+                               psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(out, NULL);
+    PS_VECTOR_CHECK_NULL(out->bounds, NULL);
+    PS_VECTOR_CHECK_TYPE(out->bounds, PS_TYPE_F32, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(out->bounds->n, NULL);
+    PS_VECTOR_CHECK_NULL(out->nums, NULL);
+    PS_VECTOR_CHECK_TYPE(out->nums, PS_TYPE_F32, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(out->nums->n, NULL);
+    PS_VECTOR_CHECK_NULL(in, out);
+    if (mask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(in, mask, NULL);
+        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+    }
+    if (errors != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(in, errors, NULL);
+        PS_VECTOR_CHECK_TYPE(errors, in->type.type, NULL);
+    }
+
+    psS32 i = 0;                  // Loop index variable
+    psF32 binSize = 0.0;          // Histogram bin size
+    psS32 binNum = 0;             // A temporary bin number
+    psS32 numBins = 0;            // The total number of bins
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+    psVector* inF32 = NULL;
+    psVector* errorsF32 = NULL;
+    psS32 mustFreeVectorIn = 1;
+    psS32 mustFreeVectorErrors = 1;
+
+    // Convert input and errors vectors to F32 if necessary.
+    inF32 = p_psConvertToF32((psVector *) in);
+    if (inF32 == NULL) {
+        inF32 = (psVector *) in;
+        mustFreeVectorIn = 0;
+    }
+    errorsF32 = p_psConvertToF32((psVector *) errors);
+    if (errorsF32 == NULL) {
+        errorsF32 = (psVector *) errors;
+        mustFreeVectorErrors = 0;
+    }
+
+    numBins = out->nums->n;
+    for (i = 0; i < inF32->n; i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) || ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            if (inF32->data.F32[i] < out->bounds->data.F32[0]) {
+                // If this pixel is below minimum value, count it, then skip.
+                out->minNum++;
+            } else if (inF32->data.F32[i] > out->bounds->data.F32[numBins]) {
+                // If this pixel is above maximum value, count it, then skip.
+                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 = (psS32)((inF32->data.F32[i] - out->bounds->data.F32[0]) / binSize);
+                    if (errorsF32 != NULL) {
+                        // XXX: Check return codes.
+                        UpdateHistogramBins(binNum, out,
+                                            inF32->data.F32[i],
+                                            errorsF32->data.F32[i]);
+                    } else {
+                        // XXX: This if-statement really shouldn't be necessary.
+                        // However, due to numerical lack of precision, we
+                        // occasionally produce a binNum outside the range.
+                        if (binNum >= out->nums->n) {
+                            binNum = out->nums->n - 1;
+                        }
+                        (out->nums->data.F32[binNum])+= 1.0;
+                    }
+
+                } else {
+                    // If this is a non-uniform histogram, determining the
+                    // correct bin number requires a bit more work.
+                    tmpScalar.data.F32 = inF32->data.F32[i];
+                    binNum = p_psVectorBinDisect(out->bounds, &tmpScalar);
+                    if (binNum < 0) {
+                        psLogMsg(__func__, PS_LOG_WARN,
+                                 "WARNING: psVectorHistogram(): element outside histogram bounds.\n");
+                    } else {
+                        if (errorsF32 != NULL) {
+                            // XXX: Check return codes.
+                            UpdateHistogramBins(binNum, out,
+                                                inF32->data.F32[i],
+                                                errors->data.F32[i]);
+                        } else {
+                            (out->nums->data.F32[binNum])+= 1.0;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (mustFreeVectorIn == 1) {
+        psFree(inF32);
+    }
+    if (mustFreeVectorErrors == 1) {
+        psFree(errorsF32);
+    }
+    return (out);
+}
+
+/******************************************************************************
+p_psConvertToF32(in): 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 Opterons...
+ *****************************************************************************/
+psVector* p_psConvertToF32(psVector* in)
+{
+    if (in == NULL) {
+        return(NULL);
+    }
+    psS32 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] = (psF32)in->data.S8[i];
+        }
+    } else if (in->type.type == PS_TYPE_S16) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32) in->data.S16[i];
+        }
+    } else if (in->type.type == PS_TYPE_S32) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.S32[i];
+        }
+    } else if (in->type.type == PS_TYPE_S64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.S64[i];
+        }
+    } else if (in->type.type == PS_TYPE_U8) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U8[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] = (psF32)in->data.U16[i];
+        }
+    } else if (in->type.type == PS_TYPE_U32) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U32[i];
+        }
+    } else if (in->type.type == PS_TYPE_U64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U64[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] = (psF32)in->data.F64[i];
+        }
+    } else if (in->type.type == PS_TYPE_F32) {
+        // do nothing
+    } else {
+        psS8* strType;
+        PS_TYPE_NAME(strType, in->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED,
+                strType);
+    }
+    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.
+ *****************************************************************************/
+psStats* psVectorStats(psStats* stats,
+                       psVector* in,
+                       psVector* errors,
+                       psVector* mask,
+                       psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(stats, NULL);
+    PS_VECTOR_CHECK_NULL(in, stats);
+    if (mask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(mask, in, stats);
+        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, stats);
+    }
+    if (errors != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(errors, in, stats);
+        PS_VECTOR_CHECK_TYPE(errors, in->type.type, stats);
+    }
+
+    psVector* inF32 = NULL;
+    psVector* errorsF32 = NULL;
+    psS32 mustFreeVectorIn = 1;
+    psS32 mustFreeVectorErrors = 1;
+
+    inF32 = p_psConvertToF32((psVector *) in);
+    if (inF32 == NULL) {
+        inF32 = in;
+        mustFreeVectorIn = 0;
+    }
+    errorsF32 = p_psConvertToF32((psVector *) errors);
+    if (errorsF32 == NULL) {
+        errorsF32 = errors;
+        mustFreeVectorErrors = 0;
+    }
+
+    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
+        PS_FLOAT_COMPARE(stats->min, stats->max, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        if (false == p_psVectorSampleMedian(inF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMedian() returned an error.\n");
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
+        }
+        p_psVectorSampleStdev(inF32, errorsF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        if (false == p_psVectorSampleQuartiles(inF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleQuartiles() returned an error.\n");
+        }
+    }
+    // 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)) {
+        if (0 != p_psVectorRobustStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psStats_STATS_FAILED);
+            // XXX: Set to NAN
+        }
+    }
+
+    // XXX: Different conditions for return -1 and -2?
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        if (-1 >  p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate clipped statistics for input psVector.\n");
+            stats->clippedMean = NAN;
+            stats->clippedStdev = NAN;
+        } else if (-2 == p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN, "Failed to calculate clipped statistics for input psVector.");
+            stats->clippedMean = NAN;
+            stats->clippedStdev = NAN;
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        if (0 != p_psVectorMax(inF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate vector maximum");
+            psFree(stats);
+            return(NULL);
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        if (0 != p_psVectorMin(inF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate vector minimum");
+            psFree(stats);
+            return(NULL);
+        }
+    }
+
+    if (mustFreeVectorIn == 1) {
+        psFree(inF32);
+    }
+    if (mustFreeVectorErrors == 1) {
+        psFree(errorsF32);
+    }
+    return (stats);
+}
+
Index: /branches/rel4/psLib/src/dataManip/psStats.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psStats.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psStats.h	(revision 3057)
@@ -0,0 +1,191 @@
+
+/** @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.37 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-22 05:09:32 $
+ *
+ *  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
+{
+    psF64 sampleMean;          ///< formal mean of sample
+    psF64 sampleMedian;        ///< formal median of sample
+    psF64 sampleStdev;         ///< standard deviation of sample
+    psF64 sampleUQ;            ///< upper quartile of sample
+    psF64 sampleLQ;            ///< lower quartile of sample
+    psF64 robustMean;          ///< robust mean of array
+    psF64 robustMedian;        ///< robust median of array
+    psF64 robustMode;          ///< Robust mode of array
+    psF64 robustStdev;         ///< robust standard deviation of array
+    psF64 robustUQ;            ///< robust upper quartile
+    psF64 robustLQ;            ///< robust lower quartile
+    psS32 robustN50;              ///<
+    psS32 robustNfit;             ///<
+    psF64 clippedMean;         ///< Nsigma clipped mean
+    psF64 clippedStdev;        ///< standard deviation after clipping
+    psS32 clippedNvalues;         ///< ???
+    psF64 clipSigma;           ///< Nsigma used for clipping; user input
+    psS32 clipIter;               ///< Number of clipping iterations; user input
+    psF64 min;                 ///< minimum data value in array
+    psF64 max;                 ///< maximum data value in array
+    psF64 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.
+    psVector* errors,  ///< Errors.
+    psVector* mask,    ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+    psU32 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)
+    psS32 minNum;                        ///< Number below the minimum
+    psS32 maxNum;                        ///< Number above the maximum
+    psBool 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(
+    psF32 lower,                       ///< Lower limit for the bins
+    psF32 upper,                       ///< Upper limit for the bins
+    psS32 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 errors,   ///< Errors
+    const psVector* restrict mask,     ///< Mask dat for input vector
+    psU32 maskVal               ///< Mask value
+);
+
+/** Extracts the statistic value specified by stats->options.
+ *
+ *  @return psBool    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.
+ */
+psBool p_psGetStatValue(
+    const psStats* stats,
+    ///< the statistic struct to operate on
+
+    psF64 *value
+    ///< if return is true, this is set to the specified statistic value by stats->options
+);
+
+void p_psNormalizeVectorRangeU8(psVector* myData, psU8 low, psU8 high);
+void p_psNormalizeVectorRangeU16(psVector* myData, psU16 low, psU16 high);
+void p_psNormalizeVectorRangeU32(psVector* myData, psU32 low, psU32 high);
+void p_psNormalizeVectorRangeU64(psVector* myData, psU64 low, psU64 high);
+void p_psNormalizeVectorRangeS8(psVector* myData, psS8 low, psS8 high);
+void p_psNormalizeVectorRangeS16(psVector* myData, psS16 low, psS16 high);
+void p_psNormalizeVectorRangeS32(psVector* myData, psS32 low, psS32 high);
+void p_psNormalizeVectorRangeS64(psVector* myData, psS64 low, psS64 high);
+void p_psNormalizeVectorRangeF32(psVector* myData, psF32 low, psF32 high);
+void p_psNormalizeVectorRangeF64(psVector* myData, psF64 low, psF64 high);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/dataManip/psVectorFFT.c
===================================================================
--- /branches/rel4/psLib/src/dataManip/psVectorFFT.c	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psVectorFFT.c	(revision 3057)
@@ -0,0 +1,418 @@
+/** @file  psVectorFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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 psBool p_fftwWisdomImported = false;
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFFTFlags direction)
+{
+    psU32 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 {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET);
+        psFree(out);
+        return NULL;
+    }
+
+    /* check if a plan exists now */
+    if (plan == NULL) {
+        psError(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 (psS32 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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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);
+        psError(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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]) - I * cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 outNumElements;
+    psU32 inNumElements;
+    psU32 inHalfNumElements;
+    psU32 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 (psU32 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 (psU32 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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel4/psLib/src/dataManip/psVectorFFT.h
===================================================================
--- /branches/rel4/psLib/src/dataManip/psVectorFFT.h	(revision 3057)
+++ /branches/rel4/psLib/src/dataManip/psVectorFFT.h	(revision 3057)
@@ -0,0 +1,99 @@
+/** @file  psVectorFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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
+} psFFTFlags;
+
+
+/** 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
+    psFFTFlags 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/rel4/psLib/src/fft/psImageFFT.c
===================================================================
--- /branches/rel4/psLib/src/fft/psImageFFT.c	(revision 3057)
+++ /branches/rel4/psLib/src/fft/psImageFFT.c	(revision 3057)
@@ -0,0 +1,435 @@
+/** @file  psImageFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include <unistd.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 psBool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFFTFlags direction)
+{
+    psU32 numCols;
+    psU32 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) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE);
+            psFree(out);
+            return NULL;
+        }
+        if ((direction & PS_FFT_REAL_RESULT) != 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED);
+            psFree(out);
+            return NULL;
+        }
+    } else if ((direction & PS_FFT_REVERSE) == 0) {
+        psError(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.
+    psS32 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) {
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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);
+        psError(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) {
+        psError(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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]) - I * cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 numRows;
+    psS32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel4/psLib/src/fft/psImageFFT.h
===================================================================
--- /branches/rel4/psLib/src/fft/psImageFFT.h	(revision 3057)
+++ /branches/rel4/psLib/src/fft/psImageFFT.h	(revision 3057)
@@ -0,0 +1,87 @@
+/** @file  psImageFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psImage
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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 psFFTFlags
+
+/// @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
+    psFFTFlags 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/rel4/psLib/src/fft/psVectorFFT.c
===================================================================
--- /branches/rel4/psLib/src/fft/psVectorFFT.c	(revision 3057)
+++ /branches/rel4/psLib/src/fft/psVectorFFT.c	(revision 3057)
@@ -0,0 +1,418 @@
+/** @file  psVectorFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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 psBool p_fftwWisdomImported = false;
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFFTFlags direction)
+{
+    psU32 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 {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET);
+        psFree(out);
+        return NULL;
+    }
+
+    /* check if a plan exists now */
+    if (plan == NULL) {
+        psError(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 (psS32 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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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);
+        psError(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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 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 (psU32 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 (psU32 i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]) - I * cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 outNumElements;
+    psU32 inNumElements;
+    psU32 inHalfNumElements;
+    psU32 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 (psU32 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 (psU32 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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel4/psLib/src/fft/psVectorFFT.h
===================================================================
--- /branches/rel4/psLib/src/fft/psVectorFFT.h	(revision 3057)
+++ /branches/rel4/psLib/src/fft/psVectorFFT.h	(revision 3057)
@@ -0,0 +1,99 @@
+/** @file  psVectorFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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
+} psFFTFlags;
+
+
+/** 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
+    psFFTFlags 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/rel4/psLib/src/fileUtils/Makefile
===================================================================
--- /branches/rel4/psLib/src/fileUtils/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/Makefile	(revision 3057)
@@ -0,0 +1,60 @@
+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 -I../astronomy -DSER7_FILE="\"$(SER7_FILE)\"" -DTAIUTC_FILE="\"$(TAIUTC_FILE)\""
+
+SRC_OBJS = psLookupTable.o \
+	psFits.o
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h)
+
+all: $(TARGET_STATIC)
+
+psFileUtilsErrors.h: psFileUtilsErrors.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 'fileUtils'"
+	$(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/rel4/psLib/src/fileUtils/psFileUtilsErrors.dat
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 3057)
@@ -0,0 +1,57 @@
+#
+#  This file is used to generate psFileUtilsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERROR_TEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+psLookupTable_FILE_NOT_FOUND           Failed to open file %s.
+psLookupTable_PARSE_VALUE              Unable to parse string, %s on line %lld.
+psLookupTable_PARSE_TYPE               Unable to parse type, %s on line %lld.
+psLookupTable_PARSE_GENERAL            Unable to read lookup table item, %s on line %lld
+psLookupTable_INTERPOLATE_HIGH         High index too big, %d.
+psLookupTable_INTERPOLATE_LOW          Low index too small, %d.
+psLookupTable_DIVIDE_BY_ZERO           Divide by zero error during interpolation.
+psLookupTable_INVALID_TYPE             Invalid psLookupType, %d;
+#
+psFits_NULL                            The input psFits object can not NULL.
+psFits_FILENAME_INVALID                Could not open file,'%s'.\nCFITSIO Error: %s
+psFits_FILENAME_NULL                   Specified filename can not be NULL.
+psFits_EXTNAME_NULL                    Specified extension name can not be NULL.
+psFits_EXTNAME_INVALID                 Could not find HDU '%s' in file %s.\nCFITSIO Error: %s
+psFits_EXTNUM_ABS_MOVE_FAILED          Could not move to specified HDU #%d in file %s.\nCFITSIO Error: %s
+psFits_EXTNUM_REL_MOVE_FAILED          Could not move %d HDUs from current position in file %s.\nCFITSIO Error: %s
+psFits_GET_EXTNUM_FAILED               Failed to determine the current HDU number in file %s.\nCFITSIO Error: %s
+psFits_GETNUMHDUS_FAILED               Failed to determine the number of HDUs in file %s.\nCFITSIO Error: %s
+psFits_GETHDUTYPE_FAILED               Failed to determine an HDU type in file %s.\nCFITSIO Error: %s
+psFits_GETNUMKEYS_FAILED               Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s
+psFits_GET_TABLE_SIZE_FAILED           Failed to determine the size of the current HDU table.\nCFITSIO Error: %s
+psFits_FILENAME_CREATE_FAILED          Could not create file,'%s'.\nCFITSIO Error: %s
+psFits_TYPE_UNSUPPORTED                Specified type, %s, is not supported.
+psFits_CREATE_HDU_FAILED               Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s
+psFits_GET_HDU_TYPE_FAILED             Could not determine the HDU type.\nCFITSIO Error: %s
+psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
+psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
+psFits_TABLE_EMPTY                     Can't create a table without any rows.
+psFits_CFITSIO_ERROR                   CFITSIO error: %s
+psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
+psFits_METADATA_ADD_FAILED             Failed to add metadata item, %s.
+psFits_WRITE_FAILED                    Could not write data to file,'%s'.\nCFITSIO Error: %s
+psFits_IMAGE_NULL                      The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
+psFits_METADATA_NULL                   The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed.
+psFits_METADATA_PTYPE_UNSUPPORTED      A metadata item's primative type, %d, is not supported.
+psFits_ROW_INVALID                     Specified row, %d, is not valid for current table of %d rows.
+psFits_GET_TABLE_ELEMENT               Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s
+psFits_FIND_COLUMN                     Specified column, %s, was not found.\nCFITSIO Error: %s
+psFits_GET_COLTYPE                     Could not determine the datatype of the table column.\nCFITSIO Error: %s
+psFits_TABLE_READ_COL                  Failed to read table column.\nCFITSIO Error: %s
+psFits_DATATYPE_UNKNOWN                Could not determine image data type.\nCFITSIO Error: %s
+psFits_IMAGE_DIM_UNKNOWN               Could not determine image dimensions.\nCFITSIO Error: %s
+psFits_IMAGE_DIMENSION_UNSUPPORTED     Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O.
+psFits_IMAGE_SIZE_UNKNOWN              Could not determine image size.\nCFITSIO Error: %s
+psFits_FITS_TYPE_UNSUPPORTED           FITS image type, BITPIX=%d, is not supported.
+psFits_READ_FAILED                     Reading FITS file failed.\nCFITSIO Error: %s
+psFits_IMAGE_UPDATE_TYPE_MISMATCH      Can not update a %s image given a %s image.
+psFits_FITS_Z_SMALL                    Current FITS HDU has %d z-planes, but z-plane %d was specified.
+#
Index: /branches/rel4/psLib/src/fileUtils/psFileUtilsErrors.h
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 3057)
@@ -0,0 +1,81 @@
+/** @file  psFileUtilsErrors.h
+ *
+ *  @brief Contains the error text for the fileUtils functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FILEUTIL_ERRORS_H
+#define PS_FILEUTIL_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_psLookupTable_FILE_NOT_FOUND "Failed to open file %s."
+#define PS_ERRORTEXT_psLookupTable_PARSE_VALUE "Unable to parse string, %s on line %lld."
+#define PS_ERRORTEXT_psLookupTable_PARSE_TYPE "Unable to parse type, %s on line %lld."
+#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL "Unable to read lookup table item, %s on line %lld"
+#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH "High index too big, %d."
+#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW "Low index too small, %d."
+#define PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO "Divide by zero error during interpolation."
+#define PS_ERRORTEXT_psLookupTable_INVALID_TYPE "Invalid psLookupType, %d;"
+#define PS_ERRORTEXT_psFits_NULL "The input psFits object can not NULL."
+#define PS_ERRORTEXT_psFits_FILENAME_INVALID "Could not open file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FILENAME_NULL "Specified filename can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_NULL "Specified extension name can not be NULL."
+#define PS_ERRORTEXT_psFits_EXTNAME_INVALID "Could not find HDU '%s' in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_EXTNUM_ABS_MOVE_FAILED "Could not move to specified HDU #%d in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_EXTNUM_REL_MOVE_FAILED "Could not move %d HDUs from current position in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_EXTNUM_FAILED "Failed to determine the current HDU number in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED "Failed to determine the number of HDUs in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED "Failed to determine an HDU type in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED "Failed to determine the number of header keys in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED "Failed to determine the size of the current HDU table.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED "Could not create file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED "Specified type, %s, is not supported."
+#define PS_ERRORTEXT_psFits_CREATE_HDU_FAILED "Could not create new image HDU in file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED "Could not determine the HDU type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
+#define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
+#define PS_ERRORTEXT_psFits_TABLE_EMPTY "Can't create a table without any rows."
+#define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
+#define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
+#define PS_ERRORTEXT_psFits_METADATA_ADD_FAILED "Failed to add metadata item, %s."
+#define PS_ERRORTEXT_psFits_WRITE_FAILED "Could not write data to file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_NULL "The input psImage was NULL.  Need a non-NULL psImage for operation to be performed."
+#define PS_ERRORTEXT_psFits_METADATA_NULL "The input psMetadata was NULL.  Need a non-NULL psMetadata for operation to be performed."
+#define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED "A metadata item's primative type, %d, is not supported."
+#define PS_ERRORTEXT_psFits_ROW_INVALID "Specified row, %d, is not valid for current table of %d rows."
+#define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT "Failed to retrieve table element (%d,%d).\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FIND_COLUMN "Specified column, %s, was not found.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_GET_COLTYPE "Could not determine the datatype of the table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_TABLE_READ_COL "Failed to read table column.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN "Could not determine image data type.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN "Could not determine image dimensions.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED "Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O."
+#define PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN "Could not determine image size.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, is not supported."
+#define PS_ERRORTEXT_psFits_READ_FAILED "Reading FITS file failed.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH "Can not update a %s image given a %s image."
+#define PS_ERRORTEXT_psFits_FITS_Z_SMALL "Current FITS HDU has %d z-planes, but z-plane %d was specified."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/fileUtils/psFits.c
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psFits.c	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psFits.c	(revision 3057)
@@ -0,0 +1,1622 @@
+/** @file  psFits.c
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 20:01:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+
+#include "psFits.h"
+#include "string.h"
+#include "psError.h"
+#include "psFileUtilsErrors.h"
+#include "psImageExtraction.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psLogMsg.h"
+#include "psTrace.h"
+
+#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
+
+static char* standardFitsKeys[] = {
+                                      "SIMPLE",
+                                      "BITPIX",
+                                      "NAXIS",
+                                      "NAXIS1",
+                                      "NAXIS2",
+                                      "NAXIS3",
+                                      "EXTEND",
+                                      "COMMENT",
+                                      "EXTNAME",
+                                      "HDUNAME",
+                                      "XTENSION",
+                                      "TFIELDS",
+                                      NULL
+                                  };
+
+static psElemType convertFitsToPsType(int datatype)
+{
+    switch (datatype) {
+    case TBYTE:
+        return PS_TYPE_U8;
+    case TSBYTE:
+        return PS_TYPE_S8;
+    case TSHORT:
+        return PS_TYPE_S16;
+    case TUSHORT:
+        return PS_TYPE_U16;
+    case TLONG:
+        if (sizeof(long) == 8) {
+            return PS_TYPE_S64;
+        }
+        // no break
+    case TINT:
+        return PS_TYPE_S32;
+    case TULONG:
+        if (sizeof(unsigned long) == 8) {
+            return PS_TYPE_U64;
+        }
+        // no break
+    case TUINT:
+        return PS_TYPE_U32;
+    case TLONGLONG:
+        return PS_TYPE_S64;
+    case TFLOAT:
+        return PS_TYPE_F32;
+    case TDOUBLE:
+        return PS_TYPE_F64;
+    case TCOMPLEX:
+        return PS_TYPE_C32;
+    case TDBLCOMPLEX:
+        return PS_TYPE_C64;
+    default:
+        return PS_TYPE_PTR;
+    }
+}
+
+
+static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
+{
+
+    int bitpix;
+    int datatype;
+    double bzero = 0.0;
+
+    switch (type) {
+
+    case PS_TYPE_U8:
+        bitpix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+
+    case PS_TYPE_S8:
+        bitpix = BYTE_IMG;
+        bzero = INT8_MIN;
+        datatype = TSBYTE;
+        break;
+
+    case PS_TYPE_U16:
+        bitpix = SHORT_IMG;
+        bzero = -1.0 * INT16_MIN;
+        datatype = TUSHORT;
+        break;
+
+    case PS_TYPE_S16:
+        bitpix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+
+    case PS_TYPE_U32:
+        bitpix = LONG_IMG;
+        bzero = -1.0 * 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,type);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED,
+                    typeStr);
+            return false;
+        }
+    }
+
+    // pass the requested parameters  (NULL parameters are not set, of course).
+    if (bitPix != NULL) {
+        *bitPix = bitpix;
+    }
+
+    if (dataType != NULL) {
+        *dataType = datatype;
+    }
+
+    if (bZero != NULL) {
+        *bZero = bzero;
+    }
+
+    return true;
+}
+
+static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
+{
+    switch (type) {
+    case PS_TYPE_BOOL:
+        *fitsType = psStringCopy("1L");
+        break;
+    case PS_TYPE_S32:
+        *fitsType = psStringCopy("1J");
+        break;
+    case PS_TYPE_F32:
+        *fitsType = psStringCopy("1E");
+        break;
+    case PS_TYPE_F64:
+        *fitsType = psStringCopy("1D");
+        break;
+        // XXX: Handle other types, e.g., Vectors, etc.
+    default:
+        return false;
+    }
+
+    return true;
+}
+
+static bool isHDUEmpty(psFits* fits)
+{
+    /* check for keys - no keys means this is really an empty HDU */
+    int keysexist = -1;
+    int morekeys;
+    int status = 0;
+
+    fits_get_hdrspace(fits->p_fd, &keysexist, &morekeys, &status);
+
+    // if no keys exist and not primary HDU, this really is an empty HDU
+    if (keysexist == 0) {
+        return true;
+    }
+
+    return false;
+
+}
+
+static void fitsFree(psFits* fits)
+{
+    int status = 0;
+
+    if (fits != NULL) {
+        (void)fits_close_file(fits->p_fd, &status);
+        psFree((void*)fits->filename);
+    }
+}
+
+psFits* psFitsAlloc(const char* name)
+{
+    int status = 0;
+    fitsfile *fptr = NULL;      /* Pointer to the FITS file */
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_FILENAME_NULL);
+        return NULL;
+    }
+
+    /* Open/Create the FITS file */
+    if (access(name, F_OK) == 0) {     // file exists
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psFits_FILENAME_INVALID,
+                    name, fitsErr);
+            return NULL;
+        }
+    } else {  // file does not exist, so create.
+        (void)fits_create_file(&fptr, name, &status);
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED,
+                    name, fitsErr);
+            return NULL;
+        }
+    }
+
+    psFits* fits = psAlloc(sizeof(psFits));
+    fits->filename = psAlloc(strlen(name)+1);
+    fits->p_fd = fptr;
+    strcpy((char*)fits->filename,name);
+    p_psMemSetDeallocator(fits,(psFreeFcn)fitsFree);
+
+    return fits;
+}
+
+bool psFitsMoveExtName(psFits* fits,
+                       const char* extname)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+
+    if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_EXTNAME_INVALID,
+                extname, fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsMoveExtNum(psFits* fits,
+                      int extnum,
+                      bool relative)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    int status = 0;
+    int hdutype = 0;
+
+    if (relative) {
+        fits_movrel_hdu(fits->p_fd, extnum, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_REL_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    } else {
+        fits_movabs_hdu(fits->p_fd, extnum+1, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_ABS_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+int psFitsGetExtNum(psFits* fits)
+{
+    int hdunum;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+
+    return fits_get_hdu_num(fits->p_fd,&hdunum) - 1;
+}
+
+char* psFitsGetExtName(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    int status = 0;
+    char name[MAX_STRING_LENGTH];
+
+    if (fits_read_key_str(fits->p_fd, "EXTNAME", name, NULL, &status) != 0) {
+        status = 0;
+        if (fits_read_key_str(fits->p_fd, "HDUNAME", name, NULL, &status) != 0) {
+            int num = psFitsGetExtNum(fits);
+            snprintf(name, MAX_STRING_LENGTH, "EXT-%3d",num);
+        }
+    }
+    return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+int psFitsGetSize(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return 0;
+    }
+
+    int num = 0;
+    int status = 0;
+
+    if (fits_get_num_hdus(fits->p_fd, &num, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED,
+                fits->filename, fitsErr);
+        return 0;
+    }
+
+    return num;
+}
+
+psFitsType psFitsGetExtType(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    int status = 0;
+    int hdutype = PS_FITS_TYPE_NONE;
+
+    if (fits_get_hdu_type(fits->p_fd, &hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED,
+                fits->filename, fitsErr);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    if (hdutype == PS_FITS_TYPE_IMAGE &&
+            psFitsGetExtNum(fits) > 0 &&
+            isHDUEmpty(fits)) {
+        return PS_FITS_TYPE_ANY;
+    }
+
+    return hdutype;
+}
+
+psMetadata* psFitsReadHeader(psMetadata* out,
+                             const psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psMetadataAlloc();
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psMetadata container.");
+            return NULL;
+        }
+    }
+
+    // Get number of key names
+    int numKeys = 0;
+    int keyNum = 0;
+    int status = 0;
+    fits_get_hdrpos(fits->p_fd, &numKeys, &keyNum, &status);
+
+    // Get each key name. Keywords start at one.
+    char keyType;
+    char keyName[MAX_STRING_LENGTH];
+    char keyValue[MAX_STRING_LENGTH];
+    char keyComment[MAX_STRING_LENGTH];
+    psBool tempBool;
+    psBool success;
+    psBool stdKey;
+    for (int i = 1; i <= numKeys; i++) {
+
+        fits_read_keyn(fits->p_fd, i, keyName, keyValue, keyComment, &status);
+
+        stdKey = false;
+
+        int stdKeyIdx = 0;
+        while (standardFitsKeys[stdKeyIdx] != NULL && ! stdKey) {
+            if (strcmp(keyName,standardFitsKeys[stdKeyIdx++]) == 0) {
+                stdKey = true;
+            }
+        }
+
+        if (keyValue[0] != 0) { // blank values are not handled by fits_get_keytype
+            fits_get_keytype(keyValue, &keyType, &status);
+        } else {
+            keyType = 'C';
+        }
+        if (status != 0) {
+            break;
+        }
+
+        if (! stdKey) {
+            switch (keyType) {
+            case 'X': // bit
+            case 'I': // short int.
+            case 'J': // int.
+            case 'B': // byte
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_S32,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atoi(keyValue));
+                break;
+            case 'U': // unsigned int. may not fit in a psS32
+            case 'K': // long int. can't all fit in a psS32
+            case 'F':
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_F64,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atof(keyValue));
+                break;
+            case 'C':
+                // remove the single-quotes at front/end
+                if (keyValue[0] == '\'' && keyValue[strlen(keyValue)-1] == '\'') {
+                    keyValue[strlen(keyValue)-1] = '\0';
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue+1);
+                } else {
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue);
+                }
+                break;
+            case 'L':
+                tempBool = (keyValue[0] == 'T') ? 1 : 0;
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_BOOL,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        tempBool);
+                break;
+            default:
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psFits_METATYPE_INVALID,
+                        keyType);
+                return out;
+            }
+
+            if (!success) {
+                psError(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                        keyName);
+                return out;
+            }
+        }
+
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                fitsErr);
+        return false;
+    }
+
+    return out;
+}
+
+psHash* psFitsReadHeaderSet(psHash* out,
+                            psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psHashAlloc(10);
+        // XXX: what is the appropriate number of buckets? Got 10 from psMetadataAlloc.
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psHash container.");
+            return NULL;
+        }
+    }
+
+    int size = psFitsGetSize(fits);
+
+    int origPosition = psFitsGetExtNum(fits);
+
+    for (int lcv=0; lcv < size; lcv++) {
+        psFitsMoveExtNum(fits, lcv, false);
+
+        char* name = NULL;
+        if (lcv == 0) {
+            name = psStringCopy("PHU");
+        } else {
+            name = psFitsGetExtName(fits);
+        }
+
+        psMetadata* header = psFitsReadHeader(NULL, fits);
+        if (name != NULL && header != NULL) {
+            psHashAdd(out, name, header);
+        } else { // XXX: is this a warning or error?
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "Failed to read HDU#%d header data.",
+                     lcv);
+        }
+
+        psFree(name);
+        psFree(header);
+    }
+
+    // reposition to the original position
+    psFitsMoveExtNum(fits, origPosition, false);
+
+    return out;
+}
+
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 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 */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    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:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        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:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    if (output == NULL)
+    {
+        psError(PS_ERR_UNKNOWN, false,
+                "Failed to allocate a properly sized image.");
+        return false;
+    }
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
+bool psFitsWriteImage(psFits* fits,
+                      const psMetadata* header,
+                      const psImage* input,
+                      int numZPlanes,
+                      char* extname)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    int status = 0;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    int naxis = 3;
+    long naxes[3];
+
+    naxes[0] = numCols;
+    naxes[1] = numRows;
+    naxes[2] = numZPlanes;
+
+    if (numZPlanes < 2) {
+        naxis = 2;
+    }
+
+    fits_create_img(fits->p_fd, bitPix, naxis, naxes, &status);
+
+    if (extname != NULL) {
+        fits_update_key_str(fits->p_fd, "EXTNAME", (char*)extname, NULL, &status);
+    }
+
+    if (bZero != 0) {        // set the bscale/bzero
+        fits_write_key_dbl(fits->p_fd, "BZERO", bZero, 12, "Pixel Value Offset", &status);
+        fits_write_key_dbl(fits->p_fd, "BSCALE", 1.0, 12, "Pixel Value Scale", &status);
+        fits_set_bscale(fits->p_fd, 1.0, bZero, &status);
+    }
+
+    // write the header, if any.
+    if (header != NULL) {
+        psFitsWriteHeader(header, fits);
+    }
+
+    if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
+        fits_write_img(fits->p_fd,
+                       dataType,              // datatype
+                       1,                     // writing to the first z-plane
+                       numCols*numRows,       // number of elements to write, i.e., the whole image
+                       input->data.V[0],      // the data
+                       &status);
+    } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
+        for (int row = 0; row < numRows; row++) {
+            fits_write_img(fits->p_fd,
+                           dataType,          // datatype
+                           firstPixel,
+                           numCols,           // number of elements to write, i.e., one row's worth
+                           input->data.V[row],// the raw row data
+                           &status);
+            firstPixel += numCols;  // move to next row
+        }
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+
+}
+
+bool psFitsUpdateImage(psFits* fits,
+                       const psImage* input,
+                       psRegion region,
+                       int z)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    // check to see if we are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    //check to see if the HDU has the same datatype
+    int fileBitpix;
+    int naxis;
+    long nAxes[3];
+    nAxes[2] = 1;
+    fits_get_img_param(fits->p_fd, 3, &fileBitpix, &naxis, nAxes, &status);
+
+    //check to see if the HDU has the same datatype
+    if (bitPix != fileBitpix) {
+        char* fitsTypeStr;
+        char* imageTypeStr;
+        PS_TYPE_NAME(fitsTypeStr,fileBitpix);
+        PS_TYPE_NAME(imageTypeStr,input->type.type);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH,
+                fitsTypeStr, imageTypeStr);
+        return false;
+    }
+
+    //check if the HDU has the z-plane requested
+    if (z >= nAxes[2]) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_FITS_Z_SMALL,
+                nAxes[2],z);
+        return false;
+    }
+
+    // determine the region in the FITS file domain
+    long firstPixel[3];
+    long lastPixel[3];
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0) {
+        lastPixel[0] = region.x1;
+    } else {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0) {
+        lastPixel[1] = region.y1;
+    } else {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    if (firstPixel[0] < 1 || firstPixel[0] > nAxes[0] ||
+            firstPixel[1] < 1 || firstPixel[1] > nAxes[1] ||
+            lastPixel[0] < 1 || lastPixel[0] > nAxes[0] ||
+            lastPixel[1] < 1 || lastPixel[1] > nAxes[1]) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified region [%d:%d,%d:%d], is not valid given the %dx%d FITS image.",
+                region.y0,region.y1-1,region.x0,region.x1-1);
+        return false;
+
+    }
+
+    int dx = lastPixel[0] - firstPixel[0];
+    int dy = lastPixel[1] - firstPixel[1];
+    if (dx > numCols ||
+            dy > numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "The region [%d:%d,%d:%d], is not valid given the input %dx%d image.",
+                firstPixel[1]-1,lastPixel[1]-1,
+                firstPixel[0]-1,lastPixel[0]-1,
+                numCols, numRows);
+        return false;
+    }
+
+    psImage* subset;
+    if (dx != numCols || dy != numRows) {
+        // the input image needs to be subsetted
+        subset = psImageSubset((psImage*)input,0,0,dx+1,dy+1);
+    } else {
+        subset = psMemIncrRefCounter((psImage*)input);
+    }
+
+    fits_write_subset(fits->p_fd, dataType, firstPixel, lastPixel, subset->data.V[0], &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsWriteHeader(const psMetadata* header,
+                       psFits* fits)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (header == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_METADATA_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    //transverse the metadata list and add each key.
+
+    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
+    psMetadataItem* item;
+    while ( (item=psListGetNext(iter)) != NULL ) {
+        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
+            switch (item->pType) {
+            case PS_TYPE_BOOL: {
+                    int value = item->data.B;
+                    fits_update_key(fits->p_fd,
+                                    TLOGICAL,
+                                    item->name,
+                                    &value,
+                                    item->comment,
+                                    &status);
+                    break;
+                }
+            case PS_TYPE_S32:
+                fits_update_key(fits->p_fd,
+                                TINT,
+                                item->name,
+                                &item->data.S32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F32:
+                fits_update_key(fits->p_fd,
+                                TFLOAT,
+                                item->name,
+                                &item->data.F32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F64:
+                fits_update_key(fits->p_fd,
+                                TDOUBLE,
+                                item->name,
+                                &item->data.F64,
+                                item->comment,
+                                &status);
+                break;
+            default:
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
+                        item->pType);
+                break;
+            }
+        } else if (item->type == PS_META_STR) {
+            fits_update_key(fits->p_fd,
+                            TSTRING,
+                            item->name,
+                            item->data.V,
+                            item->comment,
+                            &status);
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_WRITE_FAILED,
+                    fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psMetadata* psFitsReadTableRow(psFits* fits,
+                               int row)
+{
+    long numRows;
+    int numCols;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    fits_get_num_cols(fits->p_fd, &numCols, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    // the row parameter in the proper range?
+    if (row < 0 || row >= numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psFits_ROW_INVALID,
+                row,numRows);
+        return NULL;
+    }
+
+    psMetadata* data = psMetadataAlloc();
+
+    int typecode;
+    long repeat;
+    long width;
+    char name[60];
+    for (int col = 1; col <= numCols; col++) {
+        // get the column name
+        if (hdutype == BINARY_TBL) {
+            fits_get_bcolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        } else {
+            fits_get_acolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        }
+
+        // get the column type
+        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
+
+        if (status == 0) {
+
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
+        case FITSTYPE: { \
+                NATIVETYPE value = 0; \
+                int anynul = 0; \
+                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
+                              1, 1, NULL, &value, &anynul, &status); \
+                psMetadataAdd(data,PS_LIST_TAIL, name, \
+                              PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                              "", (ps##TYPE)value); \
+                break; \
+            }
+
+            switch (typecode) {
+            case TBYTE:
+            case TSHORT:
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
+            default:
+                psTrace("psFits.psFitsReadTableRow", 2,
+                        "Column %d or row %d was of a non primitive type, %d",
+                        col, row, typecode);
+            }
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
+                    col,row,fitsErr);
+            psFree(data);
+            return NULL;
+        }
+
+    }
+
+    return data;
+}
+
+psArray* psFitsReadTableColumn(psFits* fits,
+                               const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    psArray* result = psArrayAlloc(numRows);
+
+    fits_read_col_str(fits->p_fd,
+                      colnum,
+                      1, // firstrow
+                      1, // firestelem
+                      numRows,
+                      "", // nulstr
+                      (char**)result->data,
+                      NULL,
+                      &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+psVector* psFitsReadTableColumnNum(psFits* fits,
+                                   const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    // get the column datatype.
+    int typecode;
+    long repeat;
+    long width;
+    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_COLTYPE,
+                fitsErr);
+        return NULL;
+    }
+
+    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
+
+    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
+                  1 /* firstelem */, numRows, NULL, result->data.V,
+                  NULL, &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+
+psArray* psFitsReadTable(psFits* fits)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    psArray* table = psArrayAlloc(numRows);
+
+    for (int row = 0; row < numRows; row++) {
+        table->data[row] = psFitsReadTableRow(fits,row);
+    }
+
+    return table;
+}
+
+bool psFitsWriteTable(psFits* fits,
+                      psMetadata* header,
+                      psArray* table,
+                      char* extname)
+{
+    int status = 0;
+    psMetadataItem* item;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
+
+    // find all the columns needed
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
+    columns->n=0;
+
+    // find the unique items in the array of metadata 'rows'
+    for (int row=0; row < rows; row++) {
+        psMetadata* rowMeta = table->data[row];
+        if (rowMeta != NULL) {
+            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
+                                   PS_LIST_HEAD);
+            while ( (item=psListGetNext(iter)) != NULL) {
+                if (item->type == PS_META_PRIMITIVE) {
+                    bool found = false;
+                    for (int n=0; n < columns->n && ! found; n++) {
+                        if (strcmp(item->name,
+                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
+                            found = true;
+                        }
+                    }
+                    if (! found) {
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
+                    }
+                }
+            }
+            psFree(iter);
+        }
+    }
+
+    if (columns->n == 0) { // no table columns found
+        // XXX: Error?
+        return false;
+    }
+
+    //create list of column names and types.
+    psArray* columnNames = psArrayAlloc(columns->n);
+    psArray* columnTypes = psArrayAlloc(columns->n);
+    for (int n=0; n < columns->n; n++) {
+        char* fitsType;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
+        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
+                                          &fitsType)) {
+            // XXX: error message
+            return false;
+        }
+        columnTypes->data[n] = fitsType;
+    }
+
+    fits_create_tbl(fits->p_fd,
+                    BINARY_TBL,
+                    table->n, // number of rows in table
+                    columns->n, // number of columns in table
+                    (char**)columnNames->data, // names of the columns
+                    (char**)columnTypes->data, // format of the columns
+                    NULL, // physical unit of columns
+                    extname, // extension name
+                    &status);
+
+    psFree(columnNames);
+    psFree(columnTypes);
+
+    // fill in the table elements with data
+    for (int n = 0; n < columns->n; n++) {
+        int row;
+        item = columns->data[n];
+
+        if (item->type == PS_META_PRIMITIVE) {
+            psVector* col = psVectorAlloc(table->n, item->pType);
+            switch (item->pType) {
+            case PS_TYPE_S32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_int(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S32,
+                                   &status);
+                break;
+            case PS_TYPE_F32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_flt(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F32,
+                                   &status);
+                break;
+            case PS_TYPE_F64:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_dbl(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F64,
+                                   &status);
+                break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
+            default:
+                // XXX: error message
+                break;
+            }
+            psFree(col);
+        } else if (item->type == PS_META_STR) {
+            psArray* col = psArrayAlloc(table->n);
+            for (row = 0; row < table->n; row++) {
+                col->data[row] = item->data.V;
+            }
+            fits_write_col_str(fits->p_fd,
+                               n, // column number
+                               1, // firstrow
+                               1, // firstelem
+                               table->n, // nelements
+                               (char**)col->data,
+                               &status);
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
+
+    return true;
+}
Index: /branches/rel4/psLib/src/fileUtils/psFits.h
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psFits.h	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psFits.h	(revision 3057)
@@ -0,0 +1,266 @@
+/** @file  psFits.h
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FITS_H
+#define PS_FITS_H
+
+#include<fitsio.h>
+
+#include "psType.h"
+#include "psArray.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psHash.h"
+#include "psImage.h"
+
+/// @addtogroup FileIO
+/// @{
+
+typedef enum {
+    PS_FITS_TYPE_NONE = -1,
+    PS_FITS_TYPE_IMAGE = IMAGE_HDU,
+    PS_FITS_TYPE_BINARY_TABLE = BINARY_TBL,
+    PS_FITS_TYPE_ASCII_TABLE = ASCII_TBL,
+    PS_FITS_TYPE_ANY = ANY_HDU
+} psFitsType;
+
+/** FITS file object.
+ *
+ *  This object should be considered opaque to the user; no item in this
+ *  struct should be accessed directly.
+ *
+ */
+typedef struct
+{
+    fitsfile* p_fd;                    ///< the CFITSIO fits files handle.
+    const char* filename;              ///< the filename of the fits file
+}
+psFits;
+
+/** Opens a FITS file and allocates the associated psFits object.
+ *
+ *  @return psFits*    new psFits object for the FITS files specified or
+ *                     NULL if the open of the FITS file failed
+ */
+psFits* psFitsAlloc(
+    const char* name                   ///< the FITS file name
+);
+
+/** Moves the FITS HDU to the specified extension name.
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtName(
+    psFits* fits,                      ///< the psFits object to move
+    const char* extname                ///< the extension name
+);
+
+/** Moves the FITS HDU to the specified extension number
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtNum(
+    psFits* fits,                      ///< the psFits object to move
+    int extnum,                        ///< the extension number to move to (zero is primary HDU)
+    bool relative                      ///< if true, extnum is a relative number to the current position
+);
+
+/** Get the current extension number, where 0 is the primary HDU.
+ *
+ *  @return int        Current HDU number of the psFits file or < 0 if an error
+ *                     occurred.
+ */
+int psFitsGetExtNum(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the current extension name.
+ *
+ *  @return int        Current HDU name of the psFits file or NULL if an
+ *                     error occurred.
+ */
+char* psFitsGetExtName(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
+/** Get the total number of HDUs in the FITS file.
+ *
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
+ *                     error occurred.
+ */
+int psFitsGetSize(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the extension type of the current HDU.
+ *
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
+ *                     the type could not be determined.
+ */
+psFitsType psFitsGetExtType(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads the header of the current HDU.
+ *
+ *  @return psMetadata*   the header data
+ */
+psMetadata* psFitsReadHeader(
+    psMetadata* out,
+    ///< The psMetadata to add the header data.  If null, a new psMetadata is created.
+
+    const psFits* fits                 ///< the psFits object
+);
+
+/** Reads the header of all HDUs.  The current HDU is not changed.
+ *
+ *  @return psHash*      the header data
+ */
+psHash* psFitsReadHeaderSet(
+    psHash* out,
+    ///< The psHash to add the header data via psMetadata items.  If null, a
+    ///< new psHash is created.  The keys of the psHash are the extension names
+    ///< of the cooresponding HDUs.
+
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes the values of the metadata to the current HDU header.
+ *
+ *  @return bool        if TRUE, the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteHeader(
+    const psMetadata* header,          ///< the psMetadata data in which to write
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads an image, given the desired region and z-plane.
+ *
+ *  @return psImage*     the read image or NULL if there was an error.
+ */
+psImage* psFitsReadImage(
+    psImage* out,                      ///< a psImage to recycle.
+    psFits* fits,                      ///< the psFits object
+    psRegion region,                   ///< the region in the FITS image to read
+    int z                              ///< the z-plane in the FITS image cube to read
+);
+
+/** Writes an image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteImage(
+    psFits* fits,                      ///< the psFits object
+    const psMetadata* header,          ///< header items for the new HDU.  Can be NULL.
+    const psImage* input,              ///< the image to output
+    int depth,                         ///< the number of z-planes of the FITS image data cube
+    char* extname                      ///< extension name
+);
+
+/** Updates the FITS file image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsUpdateImage(
+    psFits* fits,                      ///< the psFits object
+    const psImage* input,              ///< the image to output
+    psRegion region,                   ///< the region in the FITS image to write
+    int z                              ///< the z-planes of the FITS image data cube to write
+);
+
+/** Reads a table row.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psMetadata*    The table row's data.  The keys are the column names.
+ */
+psMetadata* psFitsReadTableRow(
+    psFits* fits,                      ///< the psFits object
+    int row                            ///< row number to read
+);
+
+/** Reads a table column.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*    Array of data items for the specified column or NULL
+ *                      if an error occurred.
+ */
+psArray* psFitsReadTableColumn(
+    psFits* fits,
+    const char* colname
+);
+
+/** Reads a table column of numbers.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psVector*    Vector of data for the specified column or NULL
+ *                       if an error occurred.
+ */
+psVector* psFitsReadTableColumnNum(
+    psFits* fits,                      ///< the psFits object
+    const char* colname                ///< the column name
+);
+
+
+/** Reads a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*     Array of psMetadata items, which contains the output
+ *                       data items of each row.
+ *
+ *  @see psFitsReadTableRow
+ */
+psArray* psFitsReadTable(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsReadTableRow
+ */
+bool psFitsWriteTable(
+    psFits* fits,                      ///< the psFits object
+    psMetadata* header,                ///< header items for the new HDU.  Can be NULL.
+    psArray* table,
+    ///< Array of psMetadata items, which contains the output data items of each row.
+    char* extname                      ///< extension name
+);
+
+/** Updates a FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsWriteTable
+ */
+bool psFitsUpdateTable(
+    psFits* fits,                      ///< the psFits object
+    psArray* table
+    ///< Array of psMetadata items, which contains the output data items of each row.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/fileUtils/psLookupTable.c
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psLookupTable.c	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psLookupTable.c	(revision 3057)
@@ -0,0 +1,670 @@
+/** @file  psLookupTable.c
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-16 18:53:02 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef DARWIN
+#undef __STRICT_ANSI__
+#endif
+#include <stdlib.h>
+#ifdef DARWIN
+#define __STRICT_ANSI__
+#endif
+#include <math.h>
+
+#include "psMemory.h"
+#include "psString.h"
+#include "psError.h"
+#include "psLookupTable.h"
+#include "psFileUtilsErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static bool ignoreLine(char *inString);
+static char *cleanString(char *inString, int sLen);
+static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
+static psU8 parseU8(char *inString, psParseErrorType *status);
+static psS8 parseS8(char *inString, psParseErrorType *status);
+static psU16 parseU16(char *inString, psParseErrorType *status);
+static psS16 parseS16(char *inString, psParseErrorType *status);
+static psU32 parseU32(char *inString, psParseErrorType *status);
+static psS32 parseS32(char *inString, psParseErrorType *status);
+static psU64 parseU64(char *inString, psParseErrorType *status);
+static psS64 parseS64(char *inString, psParseErrorType *status);
+static psF32 parseF32(char *inString, psParseErrorType *status);
+static psF64 parseF64(char *inString, psParseErrorType *status);
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);
+static void lookupTableFree(psLookupTable* table);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+static 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. */
+static 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;
+}
+
+
+/** 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. */
+static char* getToken(char **inString, char *delimiter, psParseErrorType *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 = PS_PARSE_ERROR_GENERAL;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a psU8. The input string must be cleaned and null terminated. */
+static psU8 parseU8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU8 value = 0.0;
+
+
+    value = (psU8)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS8. The input string must be cleaned and null terminated. */
+static psS8 parseS8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS8 value = 0.0;
+
+
+    value = (psS8)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU16. The input string must be cleaned and null terminated. */
+static psU16 parseU16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU16 value = 0.0;
+
+
+    value = (psU16)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS16. The input string must be cleaned and null terminated. */
+static psS16 parseS16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS16 value = 0.0;
+
+
+    value = (psS16)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU32. The input string must be cleaned and null terminated. */
+static psU32 parseU32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU32 value = 0.0;
+
+
+    value = (psU32)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS32. The input string must be cleaned and null terminated. */
+static psS32 parseS32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS32 value = 0.0;
+
+
+    value = (psS32)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU64. The input string must be cleaned and null terminated. */
+static psU64 parseU64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU64 value = 0.0;
+
+
+    value = (psU64)strtoull(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS64. The input string must be cleaned and null terminated. */
+static psS64 parseS64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS64 value = 0.0;
+
+
+    value = (psS64)strtoll(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF32. The input string must be cleaned and null terminated. */
+static psF32 parseF32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF32 value = 0.0;
+
+
+    value = (psF32)strtof(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF64. The input string must be cleaned and null terminated. */
+static psF64 parseF64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF64 value = 0.0;
+
+
+    value = (psF64)strtod(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status)
+{
+    psElemType type;
+
+
+    if(vec == NULL) {
+        *status = 1;
+        return;
+    }
+
+    type = vec->type.type;
+
+    switch(type) {
+    case PS_TYPE_U8:
+        vec->data.U8[index] = parseU8(strValue, status);
+        break;
+    case PS_TYPE_S8:
+        vec->data.S8[index] = parseS8(strValue, status);
+        break;
+    case PS_TYPE_U16:
+        vec->data.U16[index] = parseU16(strValue, status);
+        break;
+    case PS_TYPE_S16:
+        vec->data.S16[index] = parseS16(strValue, status);
+        break;
+    case PS_TYPE_U32:
+        vec->data.U32[index] = parseU32(strValue, status);
+        break;
+    case PS_TYPE_S32:
+        vec->data.S32[index] = parseS32(strValue, status);
+        break;
+    case PS_TYPE_U64:
+        vec->data.U64[index] = parseU64(strValue, status);
+        break;
+    case PS_TYPE_S64:
+        vec->data.S64[index] = parseS64(strValue, status);
+        break;
+    case PS_TYPE_F32:
+        vec->data.F32[index] = parseF32(strValue, status);
+        break;
+    case PS_TYPE_F64:
+        vec->data.F64[index] = parseF64(strValue, status);
+        break;
+    default:
+        *status = PS_PARSE_ERROR_TYPE;
+    }
+
+    return;
+}
+
+static psParseErrorType printError(psU64 lineCount, char* badText, psParseErrorType status)
+{
+    switch(status) {
+    case PS_PARSE_ERROR_VALUE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_VALUE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_TYPE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_TYPE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_GENERAL:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_GENERAL, badText, lineCount);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INVALID_TYPE, badText, lineCount);
+    }
+
+    return PS_LOOKUP_SUCCESS;
+}
+
+static void lookupTableFree(psLookupTable* table)
+{
+    if (table == NULL) {
+        return;
+    }
+
+    psFree(table->values);
+    psFree(table->index);
+    psFree((char*)table->fileName);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psLookupTable* psLookupTableAlloc(const char *fileName, psF64 validFrom, psF64 validTo)
+{
+    psLookupTable *outTable = NULL;
+
+
+    // Can't read table if you don't know its name
+    PS_PTR_CHECK_NULL(fileName,NULL);
+
+    // Allocate lookup table
+    outTable = (psLookupTable*)psAlloc(sizeof(psLookupTable));
+
+    // Set deallocator
+    p_psMemSetDeallocator(outTable, (psFreeFcn)lookupTableFree);
+
+    // Allocate and set metadata item comment
+    outTable->fileName = psStringCopy(fileName);
+
+    // Number of table rows and columns. Automatically resized by table read.
+    outTable->numRows = 0;
+    outTable->numCols = 0;
+
+    // Valid ranges. Automatically set by table read if both zero.
+    outTable->validFrom = validFrom;
+    outTable->validTo = validTo;
+
+    // Vector of independent index values. Filled by table read.
+    outTable->index = NULL;
+
+    // Array of dependent table values corresponding to index values. Filled by table read.
+    outTable->values = NULL;
+
+    return outTable;
+}
+
+psLookupTable* psLookupTableRead(psLookupTable *table)
+{
+    bool typeLine = true;
+    char *line = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *linePtr = NULL;
+    psParseErrorType status = PS_PARSE_SUCCESS;
+    psU64 lineCount = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psU64 failedLines = 0;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(table->fileName,NULL);
+    if((fp=fopen(table->fileName, "r")) == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_FILE_NOT_FOUND, table->fileName);
+        return table;
+    }
+
+    indexVec = table->index;
+    table->values = psArrayAlloc(1);
+    values = table->values;
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // Loop through file to get numRows, numCols, and column data types
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            if(typeLine == true) {
+
+                // Determine column types from first line in data file after comments
+                while((strType=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+                    typeLine = false;
+                    if(!strncmp(strType, "psU8", 4)) {
+                        elemType = PS_TYPE_U8;
+                    } else if(!strncmp(strType, "psS8", 4)) {
+                        elemType = PS_TYPE_S8;
+                    } else if(!strncmp(strType, "psU16", 5)) {
+                        elemType = PS_TYPE_U16;
+                    } else if(!strncmp(strType, "psS16", 5)) {
+                        elemType = PS_TYPE_S16;
+                    } else if(!strncmp(strType, "psU32", 5)) {
+                        elemType = PS_TYPE_U32;
+                    } else if(!strncmp(strType, "psS32", 5)) {
+                        elemType = PS_TYPE_S32;
+                    } else if(!strncmp(strType, "psU64", 5)) {
+                        elemType = PS_TYPE_U64;
+                    } else if(!strncmp(strType, "psS64", 5)) {
+                        elemType = PS_TYPE_S64;
+                    } else if(!strncmp(strType, "psF32", 5)) {
+                        elemType = PS_TYPE_F32;
+                    } else if(!strncmp(strType, "psF64", 5)) {
+                        elemType = PS_TYPE_F64;
+                    } else {
+                        status = PS_PARSE_ERROR_TYPE;
+                    }
+
+                    // Realloc number of columns as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorAlloc(0, elemType);
+                    } else {
+                        values = psArrayRealloc(values, numCols-1);
+                        values->n = values->nalloc;
+                        values->data[numCols-2] = psVectorAlloc(0, elemType);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strType);
+                }
+            } else {
+
+                // Parse and add values to all columns
+                numRows++;
+                numCols = 0;
+                while((strValue=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+
+                    // Realloc number of rows as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorRecycle(indexVec, numRows, indexVec->type.type);
+                        parseValue(indexVec, numRows-1, strValue, &status);
+                    } else {
+                        valuesVec = values->data[numCols-2];
+                        valuesVec = psVectorRecycle(valuesVec, numRows, valuesVec->type.type);
+                        parseValue(valuesVec, numRows-1, strValue, &status);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strValue);
+                } // end while
+            } // end else
+        } // if ignoreLine
+    } // end while
+
+    psFree(line);
+
+    // Set table for return
+    table->numRows = numRows;
+    table->numCols = numCols-1;
+    table->index = indexVec;
+    table->values = values;
+
+    fclose(fp);
+
+    return table;
+}
+
+psF64 psLookupTableInterpolate(psLookupTable *table, psF64 index, psU64 column, psLookupStatusType *status)
+{
+    psU64 hiIdx = 0;
+    psU64 loIdx = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psF64 out = 0.0;
+    psF64 denom = 0.0;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,0.0);
+    indexVec = table->index;
+    values = table->values;
+    numRows = table->numRows;
+    numCols = table->numCols;
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+    PS_PTR_CHECK_NULL(values,0.0);
+    PS_INT_CHECK_EQUALS(numRows, 0,0.0);
+    PS_INT_CHECK_EQUALS(numCols, 0,0.0);
+    PS_INT_CHECK_RANGE(column, 0, numCols-1, 0.0);
+
+
+    valuesVec = (psVector*)values->data[column];
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+
+    if(index<indexVec->data.F64[0] || index<table->validFrom) {
+
+        // Index value past top of table
+        *status = PS_LOOKUP_PAST_TOP;
+        return valuesVec->data.F64[0];
+    } else if(index>indexVec->data.F64[numRows-1] || index>table->validTo) {
+
+        // Index value past bottom of table
+        *status = PS_LOOKUP_PAST_BOTTOM;
+        return valuesVec->data.F64[numRows-1];
+    } else {
+
+        // Interpolation
+        while(index > indexVec->data.F64[hiIdx]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH, hiIdx);
+                *status = PS_LOOKUP_ERROR;
+                return 0.0;
+            }
+        }
+
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW, loIdx);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        }
+
+        denom = indexVec->data.F64[hiIdx] - indexVec->data.F64[loIdx];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        } else {
+            out = valuesVec->data.F64[loIdx]+(valuesVec->data.F64[hiIdx]-valuesVec->data.F64[loIdx])
+                  *(index-indexVec->data.F64[loIdx])/denom;
+        }
+    }
+
+    return out;
+}
+
+psVector* psLookupTableInterpolateAll(psLookupTable *table, psF64 index, psVector *stats)
+{
+    psU64 i = 0;
+    psU64 numCols = 0;
+    psVector *outVector = NULL;
+    psLookupStatusType status = PS_LOOKUP_SUCCESS;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(stats,NULL);
+    numCols = table->numCols;
+    PS_INT_CHECK_EQUALS(numCols, 0,NULL);
+
+    outVector = psVectorAlloc(numCols, PS_TYPE_F64);
+
+    // Fill vectors with results and status of results
+    for(i=0; i<numCols; i++) {
+        outVector->data.F64[i] = psLookupTableInterpolate(table, index, i, &status);
+        stats->data.U32[i] = status;
+    }
+
+    return outVector;
+}
+
Index: /branches/rel4/psLib/src/fileUtils/psLookupTable.h
===================================================================
--- /branches/rel4/psLib/src/fileUtils/psLookupTable.h	(revision 3057)
+++ /branches/rel4/psLib/src/fileUtils/psLookupTable.h	(revision 3057)
@@ -0,0 +1,112 @@
+/** @file  psLookupTable.h
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-11-09 00:38:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_LOOKUPTABLE_H
+#define PS_LOOKUPTABLE_H
+
+#include "psType.h"
+#include "psVector.h"
+#include "psArray.h"
+
+
+/** Lookup table structure
+ *
+ *  Holds table data read from external data files.
+ *
+ */
+typedef struct
+{
+    const char *fileName;              ///< Name of file with table
+    psU64 numRows;                     ///< Number of table rows
+    psU64 numCols;                     ///< Number of table columns
+    psF64 validFrom;                   ///< Lower bound for rable read
+    psF64 validTo;                     ///< Upper bound for table read
+    psVector *index;                   ///< Vector of independent index values
+    psArray *values;                   ///< Array of dependent table values corresponding to index values
+}
+psLookupTable;
+
+
+/** Lookup table lookup status and error conditions
+ *
+ *  Success, failure, and status conditions for table lookups.
+ */
+typedef enum {
+    PS_LOOKUP_SUCCESS             = 0x0000,        ///< Table lookup succeeded
+    PS_LOOKUP_PAST_TOP            = 0x0101,        ///< Lookup off top of table
+    PS_LOOKUP_PAST_BOTTOM         = 0x0102,        ///< Lookup off bottom of table
+    PS_LOOKUP_ERROR               = 0x0104         ///< Any other type of lookup error
+} psLookupStatusType;
+
+/** Lookup table parse status and error conditions
+ *
+ *  Success, failure, and status conditions for table parsing.
+ */
+typedef enum {
+    PS_PARSE_SUCCESS              = 0x0000,        ///< Table lookup succeeded
+    PS_PARSE_ERROR_TYPE           = 0x0101,        ///< Error parsing type
+    PS_PARSE_ERROR_VALUE          = 0x0102,        ///< Error parsing numerical value
+    PS_PARSE_ERROR_GENERAL        = 0x0104         ///< Any other type of lookup error
+}psParseErrorType;
+
+/** Allocator for psLookupTable struct
+ *
+ *  Allocates a new psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableAlloc(
+    const char *fileName,           ///< Name of file to read
+    psF64 validFrom,                ///< Lower bound for rable read
+    psF64 validTo                   ///< Upper bound for table read
+);
+
+/** Read lookup table
+ *
+ *  Reads a lookup table and fills corresponding psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableRead(
+    psLookupTable *table            ///< Table to read
+);
+
+/** Lookup and interpolate value from table.
+ *
+ *  Interpolates value from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psF64 psLookupTableInterpolate(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psU64 column,                   ///< Column in table to be interpolated
+    psLookupStatusType *status      ///< Status of lookup
+);
+
+/** Lookup and interpolate all values from table.
+ *
+ *  Interpolates all values from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psVector* psLookupTableInterpolateAll(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psVector *stats                 ///< Vector of status for each lookup
+);
+
+#endif
Index: /branches/rel4/psLib/src/fits/psFits.c
===================================================================
--- /branches/rel4/psLib/src/fits/psFits.c	(revision 3057)
+++ /branches/rel4/psLib/src/fits/psFits.c	(revision 3057)
@@ -0,0 +1,1622 @@
+/** @file  psFits.c
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 20:01:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+
+#include "psFits.h"
+#include "string.h"
+#include "psError.h"
+#include "psFileUtilsErrors.h"
+#include "psImageExtraction.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psLogMsg.h"
+#include "psTrace.h"
+
+#define MAX_STRING_LENGTH 256  // maximum length string for FITS routines
+
+static char* standardFitsKeys[] = {
+                                      "SIMPLE",
+                                      "BITPIX",
+                                      "NAXIS",
+                                      "NAXIS1",
+                                      "NAXIS2",
+                                      "NAXIS3",
+                                      "EXTEND",
+                                      "COMMENT",
+                                      "EXTNAME",
+                                      "HDUNAME",
+                                      "XTENSION",
+                                      "TFIELDS",
+                                      NULL
+                                  };
+
+static psElemType convertFitsToPsType(int datatype)
+{
+    switch (datatype) {
+    case TBYTE:
+        return PS_TYPE_U8;
+    case TSBYTE:
+        return PS_TYPE_S8;
+    case TSHORT:
+        return PS_TYPE_S16;
+    case TUSHORT:
+        return PS_TYPE_U16;
+    case TLONG:
+        if (sizeof(long) == 8) {
+            return PS_TYPE_S64;
+        }
+        // no break
+    case TINT:
+        return PS_TYPE_S32;
+    case TULONG:
+        if (sizeof(unsigned long) == 8) {
+            return PS_TYPE_U64;
+        }
+        // no break
+    case TUINT:
+        return PS_TYPE_U32;
+    case TLONGLONG:
+        return PS_TYPE_S64;
+    case TFLOAT:
+        return PS_TYPE_F32;
+    case TDOUBLE:
+        return PS_TYPE_F64;
+    case TCOMPLEX:
+        return PS_TYPE_C32;
+    case TDBLCOMPLEX:
+        return PS_TYPE_C64;
+    default:
+        return PS_TYPE_PTR;
+    }
+}
+
+
+static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)
+{
+
+    int bitpix;
+    int datatype;
+    double bzero = 0.0;
+
+    switch (type) {
+
+    case PS_TYPE_U8:
+        bitpix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+
+    case PS_TYPE_S8:
+        bitpix = BYTE_IMG;
+        bzero = INT8_MIN;
+        datatype = TSBYTE;
+        break;
+
+    case PS_TYPE_U16:
+        bitpix = SHORT_IMG;
+        bzero = -1.0 * INT16_MIN;
+        datatype = TUSHORT;
+        break;
+
+    case PS_TYPE_S16:
+        bitpix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+
+    case PS_TYPE_U32:
+        bitpix = LONG_IMG;
+        bzero = -1.0 * 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,type);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED,
+                    typeStr);
+            return false;
+        }
+    }
+
+    // pass the requested parameters  (NULL parameters are not set, of course).
+    if (bitPix != NULL) {
+        *bitPix = bitpix;
+    }
+
+    if (dataType != NULL) {
+        *dataType = datatype;
+    }
+
+    if (bZero != NULL) {
+        *bZero = bzero;
+    }
+
+    return true;
+}
+
+static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)
+{
+    switch (type) {
+    case PS_TYPE_BOOL:
+        *fitsType = psStringCopy("1L");
+        break;
+    case PS_TYPE_S32:
+        *fitsType = psStringCopy("1J");
+        break;
+    case PS_TYPE_F32:
+        *fitsType = psStringCopy("1E");
+        break;
+    case PS_TYPE_F64:
+        *fitsType = psStringCopy("1D");
+        break;
+        // XXX: Handle other types, e.g., Vectors, etc.
+    default:
+        return false;
+    }
+
+    return true;
+}
+
+static bool isHDUEmpty(psFits* fits)
+{
+    /* check for keys - no keys means this is really an empty HDU */
+    int keysexist = -1;
+    int morekeys;
+    int status = 0;
+
+    fits_get_hdrspace(fits->p_fd, &keysexist, &morekeys, &status);
+
+    // if no keys exist and not primary HDU, this really is an empty HDU
+    if (keysexist == 0) {
+        return true;
+    }
+
+    return false;
+
+}
+
+static void fitsFree(psFits* fits)
+{
+    int status = 0;
+
+    if (fits != NULL) {
+        (void)fits_close_file(fits->p_fd, &status);
+        psFree((void*)fits->filename);
+    }
+}
+
+psFits* psFitsAlloc(const char* name)
+{
+    int status = 0;
+    fitsfile *fptr = NULL;      /* Pointer to the FITS file */
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_FILENAME_NULL);
+        return NULL;
+    }
+
+    /* Open/Create the FITS file */
+    if (access(name, F_OK) == 0) {     // file exists
+        (void)fits_open_file(&fptr, name, READWRITE, &status);
+        if (fptr == NULL) { // if failed, try openning as just read-only
+            status = 0;
+            (void)fits_open_file(&fptr, name, READONLY, &status);
+        }
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psFits_FILENAME_INVALID,
+                    name, fitsErr);
+            return NULL;
+        }
+    } else {  // file does not exist, so create.
+        (void)fits_create_file(&fptr, name, &status);
+        if (fptr == NULL || status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED,
+                    name, fitsErr);
+            return NULL;
+        }
+    }
+
+    psFits* fits = psAlloc(sizeof(psFits));
+    fits->filename = psAlloc(strlen(name)+1);
+    fits->p_fd = fptr;
+    strcpy((char*)fits->filename,name);
+    p_psMemSetDeallocator(fits,(psFreeFcn)fitsFree);
+
+    return fits;
+}
+
+bool psFitsMoveExtName(psFits* fits,
+                       const char* extname)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (extname == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+
+    if (fits_movnam_hdu(fits->p_fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_EXTNAME_INVALID,
+                extname, fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsMoveExtNum(psFits* fits,
+                      int extnum,
+                      bool relative)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    int status = 0;
+    int hdutype = 0;
+
+    if (relative) {
+        fits_movrel_hdu(fits->p_fd, extnum, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_REL_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    } else {
+        fits_movabs_hdu(fits->p_fd, extnum+1, &hdutype, &status);
+        if (status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_LOCATION_INVALID, true,
+                    PS_ERRORTEXT_psFits_EXTNUM_ABS_MOVE_FAILED,
+                    extnum, fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+int psFitsGetExtNum(psFits* fits)
+{
+    int hdunum;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+
+    return fits_get_hdu_num(fits->p_fd,&hdunum) - 1;
+}
+
+char* psFitsGetExtName(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    int status = 0;
+    char name[MAX_STRING_LENGTH];
+
+    if (fits_read_key_str(fits->p_fd, "EXTNAME", name, NULL, &status) != 0) {
+        status = 0;
+        if (fits_read_key_str(fits->p_fd, "HDUNAME", name, NULL, &status) != 0) {
+            int num = psFitsGetExtNum(fits);
+            snprintf(name, MAX_STRING_LENGTH, "EXT-%3d",num);
+        }
+    }
+    return psStringCopy(name);
+}
+
+bool psFitsSetExtName(psFits* fits, const char* name)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (name == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_EXTNAME_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    if (fits_update_key_str(fits->p_fd, "EXTNAME", (char*)name, NULL, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+int psFitsGetSize(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return 0;
+    }
+
+    int num = 0;
+    int status = 0;
+
+    if (fits_get_num_hdus(fits->p_fd, &num, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED,
+                fits->filename, fitsErr);
+        return 0;
+    }
+
+    return num;
+}
+
+psFitsType psFitsGetExtType(psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    int status = 0;
+    int hdutype = PS_FITS_TYPE_NONE;
+
+    if (fits_get_hdu_type(fits->p_fd, &hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED,
+                fits->filename, fitsErr);
+        return PS_FITS_TYPE_NONE;
+    }
+
+    if (hdutype == PS_FITS_TYPE_IMAGE &&
+            psFitsGetExtNum(fits) > 0 &&
+            isHDUEmpty(fits)) {
+        return PS_FITS_TYPE_ANY;
+    }
+
+    return hdutype;
+}
+
+psMetadata* psFitsReadHeader(psMetadata* out,
+                             const psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psMetadataAlloc();
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psMetadata container.");
+            return NULL;
+        }
+    }
+
+    // Get number of key names
+    int numKeys = 0;
+    int keyNum = 0;
+    int status = 0;
+    fits_get_hdrpos(fits->p_fd, &numKeys, &keyNum, &status);
+
+    // Get each key name. Keywords start at one.
+    char keyType;
+    char keyName[MAX_STRING_LENGTH];
+    char keyValue[MAX_STRING_LENGTH];
+    char keyComment[MAX_STRING_LENGTH];
+    psBool tempBool;
+    psBool success;
+    psBool stdKey;
+    for (int i = 1; i <= numKeys; i++) {
+
+        fits_read_keyn(fits->p_fd, i, keyName, keyValue, keyComment, &status);
+
+        stdKey = false;
+
+        int stdKeyIdx = 0;
+        while (standardFitsKeys[stdKeyIdx] != NULL && ! stdKey) {
+            if (strcmp(keyName,standardFitsKeys[stdKeyIdx++]) == 0) {
+                stdKey = true;
+            }
+        }
+
+        if (keyValue[0] != 0) { // blank values are not handled by fits_get_keytype
+            fits_get_keytype(keyValue, &keyType, &status);
+        } else {
+            keyType = 'C';
+        }
+        if (status != 0) {
+            break;
+        }
+
+        if (! stdKey) {
+            switch (keyType) {
+            case 'X': // bit
+            case 'I': // short int.
+            case 'J': // int.
+            case 'B': // byte
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_S32,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atoi(keyValue));
+                break;
+            case 'U': // unsigned int. may not fit in a psS32
+            case 'K': // long int. can't all fit in a psS32
+            case 'F':
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_F64,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        atof(keyValue));
+                break;
+            case 'C':
+                // remove the single-quotes at front/end
+                if (keyValue[0] == '\'' && keyValue[strlen(keyValue)-1] == '\'') {
+                    keyValue[strlen(keyValue)-1] = '\0';
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue+1);
+                } else {
+                    success = psMetadataAdd(out,
+                                            PS_LIST_TAIL,
+                                            keyName,
+                                            PS_TYPE_PTR,
+                                            PS_META_STR,
+                                            keyComment,
+                                            keyValue);
+                }
+                break;
+            case 'L':
+                tempBool = (keyValue[0] == 'T') ? 1 : 0;
+                success = psMetadataAdd(out,
+                                        PS_LIST_TAIL,
+                                        keyName,
+                                        PS_TYPE_BOOL,
+                                        PS_META_PRIMITIVE,
+                                        keyComment,
+                                        tempBool);
+                break;
+            default:
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psFits_METATYPE_INVALID,
+                        keyType);
+                return out;
+            }
+
+            if (!success) {
+                psError(PS_ERR_UNKNOWN, false,
+                        PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                        keyName);
+                return out;
+            }
+        }
+
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_METADATA_ADD_FAILED,
+                fitsErr);
+        return false;
+    }
+
+    return out;
+}
+
+psHash* psFitsReadHeaderSet(psHash* out,
+                            psFits* fits)
+{
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (out == NULL) {
+        out = psHashAlloc(10);
+        // XXX: what is the appropriate number of buckets? Got 10 from psMetadataAlloc.
+        if (out == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to allocate a new psHash container.");
+            return NULL;
+        }
+    }
+
+    int size = psFitsGetSize(fits);
+
+    int origPosition = psFitsGetExtNum(fits);
+
+    for (int lcv=0; lcv < size; lcv++) {
+        psFitsMoveExtNum(fits, lcv, false);
+
+        char* name = NULL;
+        if (lcv == 0) {
+            name = psStringCopy("PHU");
+        } else {
+            name = psFitsGetExtName(fits);
+        }
+
+        psMetadata* header = psFitsReadHeader(NULL, fits);
+        if (name != NULL && header != NULL) {
+            psHashAdd(out, name, header);
+        } else { // XXX: is this a warning or error?
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "Failed to read HDU#%d header data.",
+                     lcv);
+        }
+
+        psFree(name);
+        psFree(header);
+    }
+
+    // reposition to the original position
+    psFitsMoveExtNum(fits, origPosition, false);
+
+    return out;
+}
+
+psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
+                         psFits* fits,    // the psFits object
+                         psRegion region, // the region in the FITS image to read
+                         int z)           // the z-plane in the FITS image cube to read
+{
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 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 */
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    if (fits == NULL)
+    {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0)
+    {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU)
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fits->p_fd, &bitPix, &status) != 0)
+    {
+        fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fits->p_fd, &nAxis, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3))
+    {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
+                nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fits->p_fd, nAxis, nAxes, &status) != 0)
+    {
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
+                fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0)
+    {
+        lastPixel[0] = region.x1;
+    } else
+    {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0)
+    {
+        lastPixel[1] = region.y1;
+    } else
+    {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    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:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        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:
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
+                bitPix);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output,
+                            lastPixel[0]-firstPixel[0]+1,
+                            lastPixel[1]-firstPixel[1]+1,
+                            datatype);
+
+    if (output == NULL)
+    {
+        psError(PS_ERR_UNKNOWN, false,
+                "Failed to allocate a properly sized image.");
+        return false;
+    }
+
+    // n.b., this assumes contiguous image buffer
+    if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0)
+    {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_READ_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    return output;
+
+}
+
+bool psFitsWriteImage(psFits* fits,
+                      const psMetadata* header,
+                      const psImage* input,
+                      int numZPlanes,
+                      char* extname)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    int status = 0;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    int naxis = 3;
+    long naxes[3];
+
+    naxes[0] = numCols;
+    naxes[1] = numRows;
+    naxes[2] = numZPlanes;
+
+    if (numZPlanes < 2) {
+        naxis = 2;
+    }
+
+    fits_create_img(fits->p_fd, bitPix, naxis, naxes, &status);
+
+    if (extname != NULL) {
+        fits_update_key_str(fits->p_fd, "EXTNAME", (char*)extname, NULL, &status);
+    }
+
+    if (bZero != 0) {        // set the bscale/bzero
+        fits_write_key_dbl(fits->p_fd, "BZERO", bZero, 12, "Pixel Value Offset", &status);
+        fits_write_key_dbl(fits->p_fd, "BSCALE", 1.0, 12, "Pixel Value Scale", &status);
+        fits_set_bscale(fits->p_fd, 1.0, bZero, &status);
+    }
+
+    // write the header, if any.
+    if (header != NULL) {
+        psFitsWriteHeader(header, fits);
+    }
+
+    if (input->parent == NULL) { // if no parent, assume that the image data is contiguous
+        fits_write_img(fits->p_fd,
+                       dataType,              // datatype
+                       1,                     // writing to the first z-plane
+                       numCols*numRows,       // number of elements to write, i.e., the whole image
+                       input->data.V[0],      // the data
+                       &status);
+    } else { // image data may not be contiguous; write one row at a time
+        int firstPixel = 1;
+        for (int row = 0; row < numRows; row++) {
+            fits_write_img(fits->p_fd,
+                           dataType,          // datatype
+                           firstPixel,
+                           numCols,           // number of elements to write, i.e., one row's worth
+                           input->data.V[row],// the raw row data
+                           &status);
+            firstPixel += numCols;  // move to next row
+        }
+    }
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+
+}
+
+bool psFitsUpdateImage(psFits* fits,
+                       const psImage* input,
+                       psRegion region,
+                       int z)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    // check to see if we are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    //check to see if the HDU has the same datatype
+    int fileBitpix;
+    int naxis;
+    long nAxes[3];
+    nAxes[2] = 1;
+    fits_get_img_param(fits->p_fd, 3, &fileBitpix, &naxis, nAxes, &status);
+
+    //check to see if the HDU has the same datatype
+    if (bitPix != fileBitpix) {
+        char* fitsTypeStr;
+        char* imageTypeStr;
+        PS_TYPE_NAME(fitsTypeStr,fileBitpix);
+        PS_TYPE_NAME(imageTypeStr,input->type.type);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH,
+                fitsTypeStr, imageTypeStr);
+        return false;
+    }
+
+    //check if the HDU has the z-plane requested
+    if (z >= nAxes[2]) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_FITS_Z_SMALL,
+                nAxes[2],z);
+        return false;
+    }
+
+    // determine the region in the FITS file domain
+    long firstPixel[3];
+    long lastPixel[3];
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0) {
+        lastPixel[0] = region.x1;
+    } else {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0) {
+        lastPixel[1] = region.y1;
+    } else {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    if (firstPixel[0] < 1 || firstPixel[0] > nAxes[0] ||
+            firstPixel[1] < 1 || firstPixel[1] > nAxes[1] ||
+            lastPixel[0] < 1 || lastPixel[0] > nAxes[0] ||
+            lastPixel[1] < 1 || lastPixel[1] > nAxes[1]) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified region [%d:%d,%d:%d], is not valid given the %dx%d FITS image.",
+                region.y0,region.y1-1,region.x0,region.x1-1);
+        return false;
+
+    }
+
+    int dx = lastPixel[0] - firstPixel[0];
+    int dy = lastPixel[1] - firstPixel[1];
+    if (dx > numCols ||
+            dy > numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "The region [%d:%d,%d:%d], is not valid given the input %dx%d image.",
+                firstPixel[1]-1,lastPixel[1]-1,
+                firstPixel[0]-1,lastPixel[0]-1,
+                numCols, numRows);
+        return false;
+    }
+
+    psImage* subset;
+    if (dx != numCols || dy != numRows) {
+        // the input image needs to be subsetted
+        subset = psImageSubset((psImage*)input,0,0,dx+1,dy+1);
+    } else {
+        subset = psMemIncrRefCounter((psImage*)input);
+    }
+
+    fits_write_subset(fits->p_fd, dataType, firstPixel, lastPixel, subset->data.V[0], &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
+}
+
+bool psFitsWriteHeader(const psMetadata* header,
+                       psFits* fits)
+{
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (header == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_METADATA_NULL);
+        return false;
+    }
+
+    int status = 0;
+
+    //transverse the metadata list and add each key.
+
+    psListIterator* iter = psListIteratorAlloc(header->list,PS_LIST_HEAD);
+    psMetadataItem* item;
+    while ( (item=psListGetNext(iter)) != NULL ) {
+        if (item->type == PS_META_PRIMITIVE) { // we only write primitive data types.
+            switch (item->pType) {
+            case PS_TYPE_BOOL: {
+                    int value = item->data.B;
+                    fits_update_key(fits->p_fd,
+                                    TLOGICAL,
+                                    item->name,
+                                    &value,
+                                    item->comment,
+                                    &status);
+                    break;
+                }
+            case PS_TYPE_S32:
+                fits_update_key(fits->p_fd,
+                                TINT,
+                                item->name,
+                                &item->data.S32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F32:
+                fits_update_key(fits->p_fd,
+                                TFLOAT,
+                                item->name,
+                                &item->data.F32,
+                                item->comment,
+                                &status);
+                break;
+            case PS_TYPE_F64:
+                fits_update_key(fits->p_fd,
+                                TDOUBLE,
+                                item->name,
+                                &item->data.F64,
+                                item->comment,
+                                &status);
+                break;
+            default:
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED,
+                        item->pType);
+                break;
+            }
+        } else if (item->type == PS_META_STR) {
+            fits_update_key(fits->p_fd,
+                            TSTRING,
+                            item->name,
+                            item->data.V,
+                            item->comment,
+                            &status);
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_WRITE_FAILED,
+                    fits->filename, fitsErr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psMetadata* psFitsReadTableRow(psFits* fits,
+                               int row)
+{
+    long numRows;
+    int numCols;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    fits_get_hdu_type(fits->p_fd,&hdutype, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    fits_get_num_cols(fits->p_fd, &numCols, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    // the row parameter in the proper range?
+    if (row < 0 || row >= numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psFits_ROW_INVALID,
+                row,numRows);
+        return NULL;
+    }
+
+    psMetadata* data = psMetadataAlloc();
+
+    int typecode;
+    long repeat;
+    long width;
+    char name[60];
+    for (int col = 1; col <= numCols; col++) {
+        // get the column name
+        if (hdutype == BINARY_TBL) {
+            fits_get_bcolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        } else {
+            fits_get_acolparms(fits->p_fd, col, name,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, &status);
+        }
+
+        // get the column type
+        fits_get_coltype(fits->p_fd, col, &typecode, &repeat, &width, &status);
+
+        if (status == 0) {
+
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
+        case FITSTYPE: { \
+                NATIVETYPE value = 0; \
+                int anynul = 0; \
+                fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
+                              1, 1, NULL, &value, &anynul, &status); \
+                psMetadataAdd(data,PS_LIST_TAIL, name, \
+                              PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                              "", (ps##TYPE)value); \
+                break; \
+            }
+
+            switch (typecode) {
+            case TBYTE:
+            case TSHORT:
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
+            default:
+                psTrace("psFits.psFitsReadTableRow", 2,
+                        "Column %d or row %d was of a non primitive type, %d",
+                        col, row, typecode);
+            }
+        }
+
+        if ( status != 0) {
+            char fitsErr[MAX_STRING_LENGTH];
+            (void)fits_get_errstatus(status, fitsErr);
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT,
+                    col,row,fitsErr);
+            psFree(data);
+            return NULL;
+        }
+
+    }
+
+    return data;
+}
+
+psArray* psFitsReadTableColumn(psFits* fits,
+                               const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    psArray* result = psArrayAlloc(numRows);
+
+    fits_read_col_str(fits->p_fd,
+                      colnum,
+                      1, // firstrow
+                      1, // firestelem
+                      numRows,
+                      "", // nulstr
+                      (char**)result->data,
+                      NULL,
+                      &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+psVector* psFitsReadTableColumnNum(psFits* fits,
+                                   const char* colname)
+{
+    int colnum = 0;
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // find the column by name
+    if ( fits_get_colnum(fits->p_fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_FIND_COLUMN,
+                colname, fitsErr);
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+
+    // get the column datatype.
+    int typecode;
+    long repeat;
+    long width;
+    if ( fits_get_eqcoltype(fits->p_fd, colnum, &typecode, &repeat, &width, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_COLTYPE,
+                fitsErr);
+        return NULL;
+    }
+
+    psVector* result = psVectorAlloc(numRows, convertFitsToPsType(typecode));
+
+    fits_read_col(fits->p_fd, typecode, colnum, 1 /* firstrow */,
+                  1 /* firstelem */, numRows, NULL, result->data.V,
+                  NULL, &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_TABLE_READ_COL,
+                fitsErr);
+        return NULL;
+    }
+
+    return result;
+}
+
+
+psArray* psFitsReadTable(psFits* fits)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    // check to see if we even are positioned on a table HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_TABLE_TYPE);
+        return NULL;
+    }
+
+    // get the size of the FITS table
+    long numRows = 0;
+    fits_get_num_rows(fits->p_fd, &numRows, &status);
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+
+    psArray* table = psArrayAlloc(numRows);
+
+    for (int row = 0; row < numRows; row++) {
+        table->data[row] = psFitsReadTableRow(fits,row);
+    }
+
+    return table;
+}
+
+bool psFitsWriteTable(psFits* fits,
+                      psMetadata* header,
+                      psArray* table,
+                      char* extname)
+{
+    int status = 0;
+    psMetadataItem* item;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return NULL;
+    }
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
+
+    // find all the columns needed
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
+    columns->n=0;
+
+    // find the unique items in the array of metadata 'rows'
+    for (int row=0; row < rows; row++) {
+        psMetadata* rowMeta = table->data[row];
+        if (rowMeta != NULL) {
+            psListIterator* iter = psListIteratorAlloc(rowMeta->list,
+                                   PS_LIST_HEAD);
+            while ( (item=psListGetNext(iter)) != NULL) {
+                if (item->type == PS_META_PRIMITIVE) {
+                    bool found = false;
+                    for (int n=0; n < columns->n && ! found; n++) {
+                        if (strcmp(item->name,
+                                   ((psMetadataItem*)(columns->data[n]))->name) == 0) {
+                            found = true;
+                        }
+                    }
+                    if (! found) {
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
+                    }
+                }
+            }
+            psFree(iter);
+        }
+    }
+
+    if (columns->n == 0) { // no table columns found
+        // XXX: Error?
+        return false;
+    }
+
+    //create list of column names and types.
+    psArray* columnNames = psArrayAlloc(columns->n);
+    psArray* columnTypes = psArrayAlloc(columns->n);
+    for (int n=0; n < columns->n; n++) {
+        char* fitsType;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
+        if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
+                                          &fitsType)) {
+            // XXX: error message
+            return false;
+        }
+        columnTypes->data[n] = fitsType;
+    }
+
+    fits_create_tbl(fits->p_fd,
+                    BINARY_TBL,
+                    table->n, // number of rows in table
+                    columns->n, // number of columns in table
+                    (char**)columnNames->data, // names of the columns
+                    (char**)columnTypes->data, // format of the columns
+                    NULL, // physical unit of columns
+                    extname, // extension name
+                    &status);
+
+    psFree(columnNames);
+    psFree(columnTypes);
+
+    // fill in the table elements with data
+    for (int n = 0; n < columns->n; n++) {
+        int row;
+        item = columns->data[n];
+
+        if (item->type == PS_META_PRIMITIVE) {
+            psVector* col = psVectorAlloc(table->n, item->pType);
+            switch (item->pType) {
+            case PS_TYPE_S32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_int(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S32,
+                                   &status);
+                break;
+            case PS_TYPE_F32:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_flt(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F32,
+                                   &status);
+                break;
+            case PS_TYPE_F64:
+                for (row = 0; row < table->n; row++) {
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
+                }
+                fits_write_col_dbl(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.F64,
+                                   &status);
+                break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
+            default:
+                // XXX: error message
+                break;
+            }
+            psFree(col);
+        } else if (item->type == PS_META_STR) {
+            psArray* col = psArrayAlloc(table->n);
+            for (row = 0; row < table->n; row++) {
+                col->data[row] = item->data.V;
+            }
+            fits_write_col_str(fits->p_fd,
+                               n, // column number
+                               1, // firstrow
+                               1, // firstelem
+                               table->n, // nelements
+                               (char**)col->data,
+                               &status);
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
+
+    return true;
+}
Index: /branches/rel4/psLib/src/fits/psFits.h
===================================================================
--- /branches/rel4/psLib/src/fits/psFits.h	(revision 3057)
+++ /branches/rel4/psLib/src/fits/psFits.h	(revision 3057)
@@ -0,0 +1,266 @@
+/** @file  psFits.h
+ *
+ *  @brief Contains Fits I/O routines
+ *
+ *  @ingroup FileIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_FITS_H
+#define PS_FITS_H
+
+#include<fitsio.h>
+
+#include "psType.h"
+#include "psArray.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psHash.h"
+#include "psImage.h"
+
+/// @addtogroup FileIO
+/// @{
+
+typedef enum {
+    PS_FITS_TYPE_NONE = -1,
+    PS_FITS_TYPE_IMAGE = IMAGE_HDU,
+    PS_FITS_TYPE_BINARY_TABLE = BINARY_TBL,
+    PS_FITS_TYPE_ASCII_TABLE = ASCII_TBL,
+    PS_FITS_TYPE_ANY = ANY_HDU
+} psFitsType;
+
+/** FITS file object.
+ *
+ *  This object should be considered opaque to the user; no item in this
+ *  struct should be accessed directly.
+ *
+ */
+typedef struct
+{
+    fitsfile* p_fd;                    ///< the CFITSIO fits files handle.
+    const char* filename;              ///< the filename of the fits file
+}
+psFits;
+
+/** Opens a FITS file and allocates the associated psFits object.
+ *
+ *  @return psFits*    new psFits object for the FITS files specified or
+ *                     NULL if the open of the FITS file failed
+ */
+psFits* psFitsAlloc(
+    const char* name                   ///< the FITS file name
+);
+
+/** Moves the FITS HDU to the specified extension name.
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtName(
+    psFits* fits,                      ///< the psFits object to move
+    const char* extname                ///< the extension name
+);
+
+/** Moves the FITS HDU to the specified extension number
+ *
+ *  @return psFitsType    The HDU type, or PS_FITS_TYPE_NONE if move failed.
+ */
+bool psFitsMoveExtNum(
+    psFits* fits,                      ///< the psFits object to move
+    int extnum,                        ///< the extension number to move to (zero is primary HDU)
+    bool relative                      ///< if true, extnum is a relative number to the current position
+);
+
+/** Get the current extension number, where 0 is the primary HDU.
+ *
+ *  @return int        Current HDU number of the psFits file or < 0 if an error
+ *                     occurred.
+ */
+int psFitsGetExtNum(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the current extension name.
+ *
+ *  @return int        Current HDU name of the psFits file or NULL if an
+ *                     error occurred.
+ */
+char* psFitsGetExtName(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Set the current extension's name
+ *
+ *  @return bool       TRUE if the extension was successfully set, otherwise FALSE.
+ */
+bool psFitsSetExtName(
+    psFits* fits,                      ///< the psFits object
+    const char* name                   ///< the extension name
+);
+
+/** Get the total number of HDUs in the FITS file.
+ *
+ *  @return int        The total number of HDUs in the FITS file or < 0 if an
+ *                     error occurred.
+ */
+int psFitsGetSize(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Get the extension type of the current HDU.
+ *
+ *  @return psFitsType The type of the current HDU.  If PS_FITS_TYPE_UNKNOWN,
+ *                     the type could not be determined.
+ */
+psFitsType psFitsGetExtType(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads the header of the current HDU.
+ *
+ *  @return psMetadata*   the header data
+ */
+psMetadata* psFitsReadHeader(
+    psMetadata* out,
+    ///< The psMetadata to add the header data.  If null, a new psMetadata is created.
+
+    const psFits* fits                 ///< the psFits object
+);
+
+/** Reads the header of all HDUs.  The current HDU is not changed.
+ *
+ *  @return psHash*      the header data
+ */
+psHash* psFitsReadHeaderSet(
+    psHash* out,
+    ///< The psHash to add the header data via psMetadata items.  If null, a
+    ///< new psHash is created.  The keys of the psHash are the extension names
+    ///< of the cooresponding HDUs.
+
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes the values of the metadata to the current HDU header.
+ *
+ *  @return bool        if TRUE, the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteHeader(
+    const psMetadata* header,          ///< the psMetadata data in which to write
+    psFits* fits                       ///< the psFits object
+);
+
+/** Reads an image, given the desired region and z-plane.
+ *
+ *  @return psImage*     the read image or NULL if there was an error.
+ */
+psImage* psFitsReadImage(
+    psImage* out,                      ///< a psImage to recycle.
+    psFits* fits,                      ///< the psFits object
+    psRegion region,                   ///< the region in the FITS image to read
+    int z                              ///< the z-plane in the FITS image cube to read
+);
+
+/** Writes an image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteImage(
+    psFits* fits,                      ///< the psFits object
+    const psMetadata* header,          ///< header items for the new HDU.  Can be NULL.
+    const psImage* input,              ///< the image to output
+    int depth,                         ///< the number of z-planes of the FITS image data cube
+    char* extname                      ///< extension name
+);
+
+/** Updates the FITS file image, given the desired region and z-plane.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsUpdateImage(
+    psFits* fits,                      ///< the psFits object
+    const psImage* input,              ///< the image to output
+    psRegion region,                   ///< the region in the FITS image to write
+    int z                              ///< the z-planes of the FITS image data cube to write
+);
+
+/** Reads a table row.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psMetadata*    The table row's data.  The keys are the column names.
+ */
+psMetadata* psFitsReadTableRow(
+    psFits* fits,                      ///< the psFits object
+    int row                            ///< row number to read
+);
+
+/** Reads a table column.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*    Array of data items for the specified column or NULL
+ *                      if an error occurred.
+ */
+psArray* psFitsReadTableColumn(
+    psFits* fits,
+    const char* colname
+);
+
+/** Reads a table column of numbers.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psVector*    Vector of data for the specified column or NULL
+ *                       if an error occurred.
+ */
+psVector* psFitsReadTableColumnNum(
+    psFits* fits,                      ///< the psFits object
+    const char* colname                ///< the column name
+);
+
+
+/** Reads a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return psArray*     Array of psMetadata items, which contains the output
+ *                       data items of each row.
+ *
+ *  @see psFitsReadTableRow
+ */
+psArray* psFitsReadTable(
+    psFits* fits                       ///< the psFits object
+);
+
+/** Writes a whole FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsReadTableRow
+ */
+bool psFitsWriteTable(
+    psFits* fits,                      ///< the psFits object
+    psMetadata* header,                ///< header items for the new HDU.  Can be NULL.
+    psArray* table,
+    ///< Array of psMetadata items, which contains the output data items of each row.
+    char* extname                      ///< extension name
+);
+
+/** Updates a FITS table.  The current HDU type must be either
+ *  PS_FITS_TYPE_BINARY_TABLE or PS_FITS_TYPE_ASCII_TABLE.
+ *
+ *  @return bool        TRUE if the write was successful, otherwise FALSE
+ *
+ *  @see psFitsWriteTable
+ */
+bool psFitsUpdateTable(
+    psFits* fits,                      ///< the psFits object
+    psArray* table
+    ///< Array of psMetadata items, which contains the output data items of each row.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/image/Makefile
===================================================================
--- /branches/rel4/psLib/src/image/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/image/Makefile	(revision 3057)
@@ -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/rel4/psLib/src/image/psImage.c
===================================================================
--- /branches/rel4/psLib/src/image/psImage.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImage.c	(revision 3057)
@@ -0,0 +1,753 @@
+/** @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.57 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 03:26:23 $
+ *
+ *  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 "psString.h"
+
+#include "psImageErrors.h"
+
+static void imageFree(psImage* image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference elements
+        psU32 oldNumRows = image->numRows;
+        psU32 oldNumCols = image->numCols;
+        psPtr* rowPtr;
+
+        for (psU32 row = 0; row < oldNumRows; row++) {
+            rowPtr = image->data.PTR[row];
+            for (psU32 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* psImageAlloc(psU32 numCols,
+                      psU32 numRows,
+                      const psElemType type)
+{
+    psS32 area = 0;
+    psS32 elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    psS32 rowSize = numCols * elementSize;        // row size in bytes.
+
+    area = numCols * numRows;
+
+    if (area < 1) {
+        psError(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(psPtr ) * numRows);
+
+    image->rawDataBuffer = psAlloc(area * elementSize);
+
+    // set the row pointers.
+    image->data.V[0] = image->rawDataBuffer;
+    for (psS32 i = 1; i < numRows; i++) {
+        image->data.V[i] = (psPtr )((int8_t *) image->data.V[i - 1] + rowSize);
+    }
+
+    *(psS32 *)&image->col0 = 0;
+    *(psS32 *)&image->row0 = 0;
+    *(psU32 *)&image->numCols = numCols;
+    *(psU32 *)&image->numRows = numRows;
+    *(psDimen* ) & image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType* ) & image->type.type = type;
+    image->parent = NULL;
+    image->children = NULL;
+
+    return image;
+}
+
+psRegion* psRegionAlloc(psF32 x0,
+                        psF32 x1,
+                        psF32 y0,
+                        psF32 y1)
+{
+    psRegion* out = psAlloc(sizeof(psRegion));
+
+    out->x0 = x0;
+    out->y0 = y0;
+    out->x1 = x1;
+    out->y1 = y1;
+
+    return out;
+}
+
+
+
+psRegion* psRegionFromString(char* region)
+{
+    psS32 col0;
+    psS32 col1;
+    psS32 row0;
+    psS32 row1;
+
+    // section should be of the form '[col0:col1,row0:row1]'
+    if (region == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_SUBSECTION_NULL);
+        return NULL;
+    }
+
+    if (sscanf(region,"[%d:%d,%d:%d]",&col0,&col1,&row0,&row1) < 4) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_SUBSECTION_INVALID,
+                region);
+        return NULL;
+    }
+
+    if (col0 > col1 || row0 > row1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED,
+                col0,col1,row0,row1);
+        return NULL;
+    }
+
+    return psRegionAlloc(col0,col1,row0,row1);
+}
+
+char* psRegionToString(psRegion* region)
+{
+    char tmpText[256]; // big enough to store any region as text
+
+    if (region == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_REGION_NULL);
+        return NULL;
+    }
+
+    snprintf(tmpText,256,"[%g:%g,%g:%g]",
+             region->x0, region->x1,
+             region->y0, region->y1);
+
+    return psStringCopy(tmpText);
+}
+
+
+psImage* psImageRecycle(psImage* old,
+                        psU32 numCols,
+                        psU32 numRows,
+                        const psElemType type)
+{
+    psS32 elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    psS32 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);
+        psError(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
+        psU32 oldNumRows = old->numRows;
+        psU32 oldNumCols = old->numCols;
+        psPtr* rowPtr;
+
+        for (psU32 row = 0; row < oldNumRows; row++) {
+            rowPtr = old->data.PTR[row];
+            for (psU32 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 = (psPtr *)psRealloc(old->data.V, numRows * sizeof(psPtr ));
+
+    // recreate the row pointers
+    old->data.V[0] = old->rawDataBuffer;
+    for (psS32 i = 1; i < numRows; i++) {
+        old->data.V[i] = (psPtr )((int8_t *) old->data.V[i - 1] + rowSize);
+    }
+
+    *(psU32 *)&old->numCols = numCols;
+    *(psU32 *)&old->numRows = numRows;
+    *(psElemType* ) & old->type.type = type;
+
+    return old;
+}
+
+psImage* psImageCopy(psImage* restrict output,
+                     const psImage* input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    psS32 elementSize;
+    psS32 elements;
+    psS32 numRows;
+    psS32 numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input == output) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psError(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) {
+        psError(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 (psS32 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(psS32 row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (psS32 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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                    typeStr);
+            psFree(output);
+
+            break;
+        }
+    }
+    return output;
+}
+
+psS32 psImageFreeChildren(psImage* image)
+{
+    psS32 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 (psS32 i=0;i<numFreed;i++) {
+            children[i]->parent = NULL;
+        }
+
+        psFree(image->children);
+        image->children = NULL;
+    }
+
+    return numFreed;
+}
+
+/*****************************************************************************
+XXX: update function description.
+ 
+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,
+                              psU32 maskVal,
+                              psC64 unexposedValue,
+                              psImageInterpolateMode mode)
+{
+
+    if (input == NULL) {
+        psError(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:                                                         \
+        psError(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);
+            psError(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, \
+        psU32 maskVal, \
+        psF64 unexposedValue) \
+{ \
+    psS32 intX = (psS32) round((psF64)(x) - 0.5 + FLT_EPSILON); \
+    psS32 intY = (psS32) round((psF64)(y) - 0.5 + FLT_EPSILON); \
+    psS32 lastX = input->numCols - 1; \
+    psS32 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, \
+        psU32 maskVal, \
+        psC64 unexposedValue) \
+{ \
+    psS32 intX = (psS32) round((psF64)(x) - 0.5); \
+    psS32 intY = (psS32) round((psF64)(y) - 0.5); \
+    psS32 lastX = input->numCols - 1; \
+    psS32 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, \
+        psU32 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; \
+    psS32 intFloorX = (psS32) floorX; \
+    psS32 intFloorY = (psS32) floorY; \
+    psS32 lastX = input->numCols - 1; \
+    psS32 lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    psBool valid00 = false; \
+    psBool valid01 = false; \
+    psBool valid10 = false; \
+    psBool 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; \
+    psBool 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; \
+    psBool 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, \
+        psU32 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; \
+    psS32 intFloorX = (psS32) floorX; \
+    psS32 intFloorY = (psS32) floorY; \
+    psS32 lastX = input->numCols - 1; \
+    psS32 lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    psBool valid00 = false; \
+    psBool valid01 = false; \
+    psBool valid10 = false; \
+    psBool 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; \
+    psBool 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; \
+    psBool 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/rel4/psLib/src/image/psImage.h
===================================================================
--- /branches/rel4/psLib/src/image/psImage.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImage.h	(revision 3057)
@@ -0,0 +1,239 @@
+/** @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.45 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 03:26:23 $
+ *
+ *  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 psU32 numCols;        ///< Number of columns in image
+    const psU32 numRows;        ///< Number of rows in image.
+    const psS32 col0;                    ///< Column position relative to parent.
+    const psS32 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.
+
+    psPtr rawDataBuffer;
+}
+psImage;
+
+/** Basic image region structure.
+ *
+ * Struct for specifying a rectangular area in an image.
+ *
+ */
+typedef struct
+{
+    psF32 x0;                         ///< the first column of the region.
+    psF32 x1;                         ///< the last column of the region.
+    psF32 y0;                         ///< the first row of the region.
+    psF32 y1;                         ///< the last row of the region.
+}
+psRegion;
+
+/** 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(
+    psU32 numCols,                     ///< Number of rows in image.
+    psU32 numRows,                     ///< Number of columns in image.
+    const psElemType type              ///< Type of data for image.
+);
+
+/** Create a psRegion with the specified attributes.
+ *
+ * Uses psLib memory allocation functions to create a psRegion the
+ * specified x0, x1, y0, and y1.
+ *
+ * @return psRegion* : Pointer to psRegion.
+ *
+ */
+psRegion* psRegionAlloc(
+    psF32 x0,                         ///< the first column of the region.
+    psF32 x1,                         ///< the last column of the region.
+    psF32 y0,                         ///< the first row of the region.
+    psF32 y1                          ///< the last row of the region.
+);
+
+/** Create a psRegion with the attribute values given as a string.
+ *
+ *  Create a psRegion with the attribute values given as a string.  The format
+ *  shall be of the standard IRAF form '[x0:x1,y0:y1]'
+ *
+ *  @return psRegion*:  A new psRegion struct, or NULL is not successful.
+ */
+psRegion* psRegionFromString(
+    char* region                       ///< image rectangular region in the form '[x0:x1,y0:y1]'
+);
+
+/** Create a string of the standard IRAF form '[x0:x1,y0:y1]' from a psRegion.
+ *
+ *  @return char*:  A new string representing the psRegion as text, or NULL
+ *                  is not successful.
+ */
+char* psRegionToString(
+    psRegion* region                   ///< the psRegion to convert to a string
+);
+
+/** 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
+    psU32 numCols,                     ///< the desired number of columns in image
+    psU32 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 psS32      Number of children freed.
+ *
+ */
+psS32 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
+    psU32 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 */ \
+        psU32 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 */ \
+        psU32 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 */ \
+        psU32 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 */ \
+        psU32 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/rel4/psLib/src/image/psImageConvolve.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageConvolve.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageConvolve.c	(revision 3057)
@@ -0,0 +1,483 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-05 21:16:14 $
+ *
+ *  Copyright 2004-2005 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(psS32 xMin, psS32 xMax, psS32 yMin, psS32 yMax)
+{
+    psKernel* result;
+    psS32 numRows;
+    psS32 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);
+
+        psS32 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);
+
+        psS32 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 (psS32 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,
+                           psBool relative)
+{
+    psS32 lastX;
+    psS32 lastY;
+    psS32 lastT;
+    psS32 x;
+    psS32 y;
+    psS32 t;
+    psS32 xMin = 0;
+    psS32 xMax = 0;
+    psS32 yMin = 0;
+    psS32 yMax = 0;
+    psS32 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) {
+        psError(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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH,
+                typeTStr, typeXStr, typeYStr);
+        return NULL;
+    }
+
+    // sizes match?
+    length = xShifts->n;
+    if (length != yShifts->n ||
+            length != tShifts->n) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "Shift vectors can not be of different sizes.");
+        return NULL;
+    }
+
+    // if no shifts, the kernel is just a 1 at 0,0
+    if (length < 1) {
+        result = psKernelAlloc(0,0,0,0);
+        result->kernel[0][0] = 1;
+        return result;
+    }
+
+    #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; \
+        lastX = xShiftData[length-1]; \
+        lastY = yShiftData[length-1]; \
+        lastT = tShiftData[length-1]; \
+        \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            x = lastX - xShiftData[lcv]; \
+            y = lastY - yShiftData[lcv]; \
+            \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        \
+        normalizeTime = 1.0 / (psKernelType)(tShiftData[length-1]); \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        psS32 prevT = 0; \
+        for (int i = 0; i < length; i++) { \
+            t = tShiftData[i] - prevT; \
+            x = lastX - xShiftData[i]; \
+            y = lastY - yShiftData[i]; \
+            \
+            kernel[y][x] += (psKernelType)t / (psKernelType)lastT; \
+            prevT = tShiftData[i]; \
+        } \
+        break; \
+    }
+
+    #define RELATIVE_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 = length-1; lcv >= 0; 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; \
+            } \
+            x -= xShiftData[lcv]; \
+            y -= yShiftData[lcv]; \
+            \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        normalizeTime = 1.0 / (psKernelType)t; \
+        x = 0; \
+        y = 0; \
+        for (psS32 i = length-1; i >= 0; i--) { \
+            kernel[y][x] += (psKernelType)(tShiftData[i]) * normalizeTime; \
+            x -= xShiftData[i]; \
+            y -= yShiftData[i]; \
+            \
+        } \
+        break; \
+    }
+
+    if (relative) {
+        switch (xShifts->type.type) {
+            RELATIVE_KERNEL_GENERATE_CASE(U8);
+            RELATIVE_KERNEL_GENERATE_CASE(U16);
+            RELATIVE_KERNEL_GENERATE_CASE(U32);
+            RELATIVE_KERNEL_GENERATE_CASE(U64);
+            RELATIVE_KERNEL_GENERATE_CASE(S8);
+            RELATIVE_KERNEL_GENERATE_CASE(S16);
+            RELATIVE_KERNEL_GENERATE_CASE(S32);
+            RELATIVE_KERNEL_GENERATE_CASE(S64);
+            RELATIVE_KERNEL_GENERATE_CASE(F32);
+            RELATIVE_KERNEL_GENERATE_CASE(F64);
+            RELATIVE_KERNEL_GENERATE_CASE(C32);
+            RELATIVE_KERNEL_GENERATE_CASE(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,xShifts->type.type);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+            }
+        }
+    } else {
+        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);
+                psError(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, psBool direct)
+{
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if (kernel == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImageConvolve_KERNEL_NULL);
+        psFree(out);
+        return NULL;
+    }
+    psS32 xMin = kernel->xMin;
+    psS32 xMax = kernel->xMax;
+    psS32 yMin = kernel->yMin;
+    psS32 yMax = kernel->yMax;
+    psKernelType** kData = kernel->kernel;
+
+    // make the output image to the proper size and type
+    psS32 numRows = in->numRows;
+    psS32 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 (psS32 row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (psS32 col=0;col<numCols;col++) { \
+                    ps##TYPE pixel = 0.0; \
+                    for (psS32 kRow = yMin; kRow < yMax; kRow++) { \
+                        if (row-kRow >= 0 && row-kRow < numRows) { \
+                            for (psS32 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);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+                psFree(out);
+                return NULL;
+
+            }
+        }
+
+
+    } else {
+        // fourier convolution
+        psS32 paddedCols = numCols+2*FOURIER_PADDING;
+        psS32 paddedRows = numRows+2*FOURIER_PADDING;
+
+        // check to see if kernel is smaller, otherwise padding it up will fail.
+        psS32 kRows = kernel->image->numRows;
+        psS32 kCols = kernel->image->numCols;
+        if (kRows >= numRows || kCols >= numCols) {
+            psError(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);
+        psS32 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.
+        psS32 sidePaddingSize = FOURIER_PADDING*elementSize;
+        psS32 imageRowSize = numCols*elementSize;
+        psU8* paddedData = paddedImage->data.U8[FOURIER_PADDING];
+        for (psS32 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
+        psS32 yMax = kernel->yMax;
+        psS32 xMax = kernel->xMax;
+        for (psS32 row = kernel->yMin; row <= yMax;row++) {
+            psS32 padRow = row;
+            if (padRow < 0) {
+                padRow += paddedRows;
+            }
+            psKernelType* padData = paddedKernel->data.PS_TYPE_KERNEL_DATA[padRow];
+            psKernelType* kernelRow = kernel->kernel[row];
+            for (psS32 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) {
+            psError(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) {
+            psError(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) {
+            psError(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 (psS32 row = 0; row < numRows; row++) {
+            psF32* outRow = out->data.F32[row];
+            psC32* resultRow = complexOutSansPad->data.C32[row];
+            for (psS32 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/rel4/psLib/src/image/psImageConvolve.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageConvolve.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageConvolve.h	(revision 3057)
@@ -0,0 +1,121 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_CONVOLVE_H
+#define PS_IMAGE_CONVOLVE_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
+    psS32 xMin;                          ///< Most negative x index
+    psS32 yMin;                          ///< Most negative y index
+    psS32 xMax;                          ///< Most positive x index
+    psS32 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(
+    psS32 xMin,                          ///< Most negative x index
+    psS32 xMax,                          ///< Most positive x index
+    psS32 yMin,                          ///< Most negative y index
+    psS32 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
+    psBool 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
+    psBool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /branches/rel4/psLib/src/image/psImageErrors.dat
===================================================================
--- /branches/rel4/psLib/src/image/psImageErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageErrors.dat	(revision 3057)
@@ -0,0 +1,80 @@
+#
+#  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_REGION_NULL                    Specified psRegion is NULL.  Operation could not be performed.
+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/rel4/psLib/src/image/psImageErrors.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageErrors.h	(revision 3057)
@@ -0,0 +1,102 @@
+/** @file  psImageErrors.h
+ *
+ *  @brief Contains the error text for the image functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-04 02: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_REGION_NULL "Specified psRegion is NULL.  Operation could not be performed."
+#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/rel4/psLib/src/image/psImageExtraction.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageExtraction.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageExtraction.c	(revision 3057)
@@ -0,0 +1,812 @@
+/** @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.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 19:14:15 $
+ *
+ *  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,
+                     psS32 col0,
+                     psS32 row0,
+                     psS32 col1,
+                     psS32 row1)
+{
+    psU32 elementSize;          // size of image element in bytes
+    psU32 inputColOffset;       // offset in bytes to first subset pixel in input row
+
+    if (image == NULL || image->data.V == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(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 ) {
+        psError(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;
+    }
+    psS32 numRows = row1-row0;
+    psS32 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'
+    psPtr 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(psPtr)*numRows); // resize row pointer array
+    *(psType*)&out->type = image->type;
+    *(psU32*)&out->numCols = numCols;
+    *(psU32*)&out->numRows = numRows;
+    *(psS32*)&out->row0 = row0;
+    *(psS32*)&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 (psS32 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.
+    psS32 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,
+                       psS32 col0,
+                       psS32 row0,
+                       psS32 col1,
+                       psS32 row1)
+{
+    return imageSubset(NULL,image,col0,row0,col1,row1);
+}
+
+psImage* psImageSubsection(psImage* image,
+                           const char* section)
+{
+    psS32 col0;
+    psS32 col1;
+    psS32 row0;
+    psS32 row1;
+
+    // section should be of the form '[col0:col1,row0:row1]'
+    if (section == NULL) {
+        psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_SUBSECTION_INVALID,
+                section);
+        return NULL;
+    }
+
+    if (col0 > col1 || row0 > row1) {
+        psError(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, psS32 col0, psS32 row0, psS32 col1, psS32 row1)
+{
+    if (image == NULL || image->data.V == NULL) {
+        psError(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 ) {
+        psError(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);
+
+    psU32 elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+    psU32 numCols = col1-col0;
+    psU32 numRows = row1-row0;
+    psU32 rowSize = elementSize*numCols;
+    psU32 colOffset = elementSize * col0;
+    psU8* imageData = image->rawDataBuffer;
+    for (psS32 row = row0; row < row1; row++) {
+        memmove(imageData,image->data.U8[row] + colOffset,rowSize);
+        imageData += rowSize;
+    }
+
+    *(psU32*)&image->numRows = numRows;
+    *(psU32*)&image->numCols = numCols;
+
+    // XXX: should I really resize the buffers?
+    image->data.V = psRealloc(image->data.V,sizeof(psPtr)*numRows);
+    image->rawDataBuffer = psRealloc(image->rawDataBuffer,rowSize*numRows);
+
+    image->data.V[0] = image->rawDataBuffer;
+    for (psS32 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,
+                       psU32 maskVal,
+                       psS32 col0,
+                       psS32 row0,
+                       psS32 col1,
+                       psS32 row1,
+                       psImageCutDirection direction,
+                       const psStats* stats)
+{
+    double statVal;
+    psStats* myStats;
+    psElemType type;
+    psS32 inRows;
+    psS32 inCols;
+    psS32 delta = 1;
+    psF64* outData;
+
+    if (in == NULL || in->data.V == NULL) {
+        psError(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) {
+        psError(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) {
+            psError(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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                    typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            return NULL;
+        }
+    }
+
+    if (stats == NULL) {
+        psError(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) {
+        psError(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;
+
+    psS32 numCols = col1-col0;
+    psS32 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 (psS32 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 (psS32 r=row0;r<row1;r++) { \
+                    *(imgVecData++) = *imgData; \
+                    imgData += inCols; \
+                    if (maskVecData != NULL) { \
+                        *(maskVecData++) = *maskData; \
+                        maskData += inCols; \
+                    } \
+                } \
+                myStats = psVectorStats(myStats,imgVec,NULL,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);
+                psError(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;
+        psS32 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 (psS32 r = row0; r < row1; r++) {
+            // point the vector struct to the
+            // data to calculate the stats
+            imgVec->data.V = (psPtr )(in->data.U8[r] + col0 * elementSize);
+            if (maskVec != NULL) {
+                maskVec->data.V = (psPtr )(mask->data.U8[r] + col0 * sizeof(psMaskType));
+            }
+            myStats = psVectorStats(myStats, imgVec, NULL, 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
+        psError(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,
+                     psU32 maskVal,
+                     float startCol,
+                     float startRow,
+                     float endCol,
+                     float endRow,
+                     psU32 nSamples,
+                     psImageInterpolateMode mode)
+{
+    if (in == NULL || in->data.V == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    psS32 numCols = in->numCols;
+    psS32 numRows = in->numRows;
+
+    if (nSamples < 2) {
+        psError(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) {
+        psError(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) {
+        psError(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) {
+            psError(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);
+            psError(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 (psS32 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);
+            psError(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,
+                           psU32 maskVal,
+                           float centerCol,
+                           float centerRow,
+                           const psVector* radii,
+                           const psStats* stats)
+{
+    double statVal;
+
+    /* check the parameters */
+
+    if (in == NULL || in->data.V == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    psS32 numCols = in->numCols;
+    psS32 numRows = in->numRows;
+
+    if (mask != NULL) {
+        if (numRows != mask->numRows || numCols != mask->numCols) {
+            psError(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);
+            psError(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) {
+        psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_RADII_VECTOR_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (radii->n < 2) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL,
+                radii->n);
+        psFree(out);
+        return NULL;
+    }
+
+    if (stats == NULL) {
+        psError(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) {
+        psError(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.
+    psS32 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;
+
+    psS32 startRow = centerRow - rSq[numOut];
+    psS32 endRow = centerRow + rSq[numOut];
+    psS32 startCol = centerCol - rSq[numOut];
+    psS32 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 (psS32 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 (psS32 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 (psS32 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 (psS32 col=startCol; col <= endCol; col++) {
+            dX = centerCol - (float)col - 0.5f;
+            dY = centerRow - (float)row - 0.5f;
+            dist = dX*dX+dY*dY;
+            for (psS32 r = 0; r < numOut; r++) {
+                if (rSq[r] < dist && dist < rSq[r+1]) {
+                    psS32 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 (psS32 r = 0; r < numOut; r++) {
+        myStats = psVectorStats(myStats,buffer[r], NULL, bufferMask[r],maskVal);
+        (void)p_psGetStatValue(myStats,&statVal);
+        outData[r] = statVal;
+    }
+
+    psFree(myStats);
+
+    for (psS32 lcv = 0; lcv < numOut; lcv++) {
+        psFree(buffer[lcv]);
+        psFree(bufferMask[lcv]);
+    }
+    psFree(buffer);
+    psFree(bufferMask);
+    psFree(rSqVec);
+    return out;
+}
Index: /branches/rel4/psLib/src/image/psImageExtraction.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageExtraction.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageExtraction.h	(revision 3057)
@@ -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.19 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-27 00:57:31 $
+*
+*  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.
+    psS32 col0,                          ///< starting column of subimage
+    psS32 row0,                          ///< starting row of subimage
+    psS32 col1,                          ///< exclusive end column of subimage.
+    psS32 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
+    psS32 col0,                          ///< column of trim region's left boundary
+    psS32 row0,                          ///< row of trim region's lower boundary
+    psS32 col1,                          ///< column of trim region's right boundary
+    psS32 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.
+    psU32 maskVal,              ///< the mask value to apply to the mask
+    psS32 col0,                          ///< the leftmost column of the slice region
+    psS32 row0,                          ///< the bottommost row of the slice region
+    psS32 col1,                          ///< exclusive end column of the slice region
+    psS32 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.
+    psU32 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
+    psU32 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.
+    psU32 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/rel4/psLib/src/image/psImageFFT.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageFFT.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageFFT.c	(revision 3057)
@@ -0,0 +1,435 @@
+/** @file  psImageFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include <unistd.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 psBool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFFTFlags direction)
+{
+    psU32 numCols;
+    psU32 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) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE);
+            psFree(out);
+            return NULL;
+        }
+        if ((direction & PS_FFT_REAL_RESULT) != 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED);
+            psFree(out);
+            return NULL;
+        }
+    } else if ((direction & PS_FFT_REVERSE) == 0) {
+        psError(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.
+    psS32 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) {
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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);
+        psError(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) {
+        psError(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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]) - I * cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psError(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;
+    psU32 numCols;
+    psU32 numRows;
+    psS32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (psU32 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 (psU32 row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (psU32 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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel4/psLib/src/image/psImageFFT.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageFFT.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageFFT.h	(revision 3057)
@@ -0,0 +1,87 @@
+/** @file  psImageFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psImage
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 22:14:17 $
+ *
+ *  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 psFFTFlags
+
+/// @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
+    psFFTFlags 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/rel4/psLib/src/image/psImageIO.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageIO.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageIO.c	(revision 3057)
@@ -0,0 +1,420 @@
+/** @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.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-12 22:17:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <fitsio.h>
+#include <unistd.h>
+
+#include "psImageIO.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+
+#include "psImageErrors.h"
+
+psImage* psImageReadSection(psImage* output,
+                            psS32 col,
+                            psS32 row,
+                            psS32 numCols,
+                            psS32 numRows,
+                            psS32 z,
+                            char *extname,
+                            psS32 extnum,
+                            char *filename)
+{
+    fitsfile *fptr = NULL;      /* Pointer to the FITS file */
+    psS32 status = 0;           /* CFITSIO file vars */
+    psS32 nAxis = 0;
+    psS32 anynull = 0;
+    psS32 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 */
+    psS32 hduType = IMAGE_HDU;
+    psS32 fitsDatatype = 0;
+    psS32 datatype = 0;
+
+    psLogMsg(__func__,PS_LOG_WARN, "psImageReadSection is deprecated.  Consider using psFitsReadImage instead.");
+
+    if (filename == NULL) {
+        psError(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);
+        psError(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);
+            psError(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);
+            psError(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);
+        psError(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);
+        psError(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);
+        psError(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);
+        psError(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:
+        datatype = PS_TYPE_S8;
+        fitsDatatype = TSBYTE;
+        break;
+    case USHORT_IMG:
+        datatype = PS_TYPE_U16;
+        fitsDatatype = TUSHORT;
+        break;
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+    case ULONG_IMG:
+        datatype = PS_TYPE_U32;
+        fitsDatatype = TUINT;
+        break;
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+    case LONGLONG_IMG:
+        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:
+        psError(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);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psImageIO_READ_FAILED,
+                filename, fitsErr);
+        return NULL;
+    }
+
+    (void)fits_close_file(fptr, &status);
+
+    return output;
+}
+
+psBool psImageWriteSection(psImage* input,
+                           psS32 col0,
+                           psS32 row0,
+                           psS32 z,
+                           char *extname,
+                           psS32 extnum,
+                           char *filename)
+{
+    psS32 numCols = 0;
+    psS32 numRows = 0;
+
+    psS32 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 */
+    psS32 datatype = 0;           /* the datatype of the image */
+    psS32 bitPix = 0;             /* FITS bitPix value */
+    psS32 hduType = IMAGE_HDU;    /* the HDU type (image,table, etc.) */
+    double bscale = 1.0;
+    double bzero = 0.0;
+    psBool createNewHDU = false;
+
+    psLogMsg(__func__,PS_LOG_WARN, "psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.");
+
+    /* need a valid image to write */
+    if (input == NULL) {
+        psError(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:
+        bitPix = BYTE_IMG;
+        bzero = INT8_MIN;
+        datatype = TSBYTE;
+        break;
+    case PS_TYPE_U16:
+        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:
+        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);
+            psError(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);
+            psError(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);
+                psError(PS_ERR_LOCATION_INVALID, true,
+                        PS_ERRORTEXT_psImageIO_EXTNAME_INVALID,
+                        extname, filename, fitsErr);
+                return false;
+            }
+        } else {
+            psS32 numHDUs = 0;
+
+            fits_get_num_hdus(fptr, &numHDUs, &status);
+            if (numHDUs < extnum) {
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(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);
+                psError(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);
+            psError(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);
+            psError(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);
+                psError(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);
+        psError(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/rel4/psLib/src/image/psImageIO.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageIO.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageIO.h	(revision 3057)
@@ -0,0 +1,96 @@
+
+/** @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.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#ifndef PS_IMAGEIO_H
+#define PS_IMAGEIO_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 */
+
+    psS32 col0,
+    /**< the column index of the origin to start reading */
+
+    psS32 row0,
+    /**< the row index of the origin to start reading */
+
+    psS32 numCols,
+    /**< the number of desired columns to read */
+
+    psS32 numRows,
+    /**< the number of desired rows to read */
+
+    psS32 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
+        */
+
+    psS32 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 psBool         TRUE is successful, otherwise FALSE.
+ */
+psBool psImageWriteSection(
+    psImage* input,
+    /**< the psImage to write */
+
+    psS32 col0,
+    /**< the column index of the origin to start writing */
+
+    psS32 row0,
+    /**< the row index of the origin to start writing */
+
+    psS32 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
+    */
+
+    psS32 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/rel4/psLib/src/image/psImageManip.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageManip.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageManip.c	(revision 3057)
@@ -0,0 +1,1048 @@
+/** @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.35 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>                          // for isfinite(), etc.
+#include <stdlib.h>
+#include <string.h>                        // for memcpy, etc.
+
+#include "psError.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psMemory.h"
+#include "psImageExtraction.h"
+#include "psConstants.h"
+#include "psImageErrors.h"
+
+psS32 psImageClip(psImage* input,
+                  psF64 min,
+                  psF64 vmin,
+                  psF64 max,
+                  psF64 vmax)
+{
+    psS32 numClipped = 0;
+    psU32 numRows;
+    psU32 numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+
+    if (max < min) {
+        psError(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) { \
+                psError(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) { \
+                psError(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 (psU32 row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (psU32 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) { \
+                psError(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) { \
+                psError(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 (psU32 row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (psU32 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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                    typeStr);
+        }
+    }
+
+    return numClipped;
+}
+
+psS32 psImageClipNaN(psImage* input,
+                     psF64 value)
+{
+    psS32 numClipped = 0;
+    psU32 numRows;
+    psU32 numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipNaNCase(type) \
+    case PS_TYPE_##type: \
+        for (psU32 row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (psU32 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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                    typeStr);
+        }
+    }
+
+    return numClipped;
+}
+
+psS32 psImageOverlaySection(psImage* image,
+                            const psImage* overlay,
+                            psS32 col0,
+                            psS32 row0,
+                            const char *op)
+{
+    psU32 imageNumRows;
+    psU32 imageNumCols;
+    psU32 overlayNumRows;
+    psU32 overlayNumCols;
+    psU32 imageRowLimit;
+    psU32 imageColLimit;
+    psElemType type;
+    psU32 pixelsOverlaid = 0;
+
+    if (image == NULL || overlay == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return pixelsOverlaid;
+    }
+
+    if (op == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImageManip_OPERATION_NULL);
+        return pixelsOverlaid;
+    }
+
+    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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH,
+                typeStrOverlay, typeStr);
+        return pixelsOverlaid;
+    }
+
+    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) {
+
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID,
+                col0, imageColLimit, row0, imageRowLimit,
+                imageNumCols, imageNumRows);
+        return pixelsOverlaid;
+    }
+
+
+    #define psImageOverlayLoop(DATATYPE,OP) { \
+        for (int row=row0;row<imageRowLimit;row++) { \
+            ps##DATATYPE* imageRow = image->data.DATATYPE[row]; \
+            ps##DATATYPE* overlayRow = overlay->data.DATATYPE[row-row0]; \
+            for (int col=col0;col<imageColLimit;col++) { \
+                imageRow[col] OP overlayRow[col-col0]; \
+            } \
+        } \
+        pixelsOverlaid += (imageRowLimit - row0) * (imageColLimit - col0); \
+    }
+
+    #define psImageOverlayCase(DATATYPE) \
+case PS_TYPE_##DATATYPE: \
+    switch (*op) { \
+    case '+': \
+        psImageOverlayLoop(DATATYPE,+=); \
+        break; \
+    case '-': \
+        psImageOverlayLoop(DATATYPE,-=); \
+        break; \
+    case '*': \
+        psImageOverlayLoop(DATATYPE,*=); \
+        break; \
+    case '/': \
+        psImageOverlayLoop(DATATYPE,/=); \
+        break; \
+    case '=': \
+        psImageOverlayLoop(DATATYPE,=); \
+        break; \
+    default: \
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+                PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID, \
+                op); \
+        return pixelsOverlaid; \
+    } \
+    break;
+
+    switch (type) {
+        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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                    typeStr);
+            return pixelsOverlaid;
+        }
+    }
+
+    return pixelsOverlaid;
+}
+
+psS32 psImageClipComplexRegion(psImage* input,
+                               psC64 min,
+                               psC64 vmin,
+                               psC64 max,
+                               psC64 vmax)
+{
+    psS32 numClipped = 0;
+    psU32 numRows;
+    psU32 numCols;
+    psF64 realMin = creal(min);
+    psF64 imagMin = cimag(min);
+    psF64 realMax = creal(max);
+    psF64 imagMax = cimag(max);
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return 0;
+    }
+
+    if (realMax < realMin) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImageManip_MAXMIN_REAL,
+                (double)realMin, (double)realMax);
+        return 0;
+    }
+    if (imagMax < imagMin) {
+        psError(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 ) { \
+            psError(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 ) { \
+            psError(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 (psU32 row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (psU32 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);
+            psError(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,
+                      psU32 scale,
+                      const psStats* stats)
+{
+    psS32 inRows;
+    psS32 inCols;
+    psS32 outRows;
+    psS32 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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (scale < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE,
+                scale);
+        psFree(out);
+        return NULL;
+    }
+
+    if (stats == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_STAT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (p_psGetStatValue(stats, &statVal) == false) {
+        psError(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);
+            psError(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 (psS32 row = 0; row < outRows; row++) { \
+            outRowData = out->data.type[row]; \
+            psS32 inCurrentRow = row*scale; \
+            psS32 inNextRow = (row+1)*scale; \
+            for (psS32 col = 0; col < outCols; col++) { \
+                psS32 inCurrentCol = col*scale; \
+                psS32 inNextCol = (col+1)*scale; \
+                psS32 n = 0; \
+                for (psS32 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 (psS32 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,NULL,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);
+            psError(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,
+                         psS32 scale,
+                         psImageInterpolateMode mode)
+{
+    psS32 outRows;
+    psS32 outCols;
+    float invScale;
+
+    if (in == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (scale < 1) {
+        psError(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) {
+        psError(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 (psS32 row=0;row<outRows;row++) { \
+            ps##TYPE* rowData = out->data.TYPE[row]; \
+            float inRow = (float)row * invScale; \
+            for (psS32 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);
+            psError(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,
+                     psS32 dx,
+                     psS32 dy)
+{
+    psS32 outRows;
+    psS32 outCols;
+    psS32 elementSize;
+
+    if (in == NULL) {
+        psError(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;
+    }
+
+    psS32 segment1Size = elementSize * (outCols - dx);
+    psS32 segment2Size = elementSize * dx;
+
+    for (psS32 row = 0; row < outRows; row++) {
+        psS32 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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    // put the angle in the range of 0...2PI.
+    angle = (float)((double)angle - (2.0*PS_PI) * floor(angle / (2.0*PS_PI)));
+
+    if (fabsf(angle - PS_PI_2) < FLT_EPSILON) {
+        // perform 1/4 rotate counter-clockwise
+        psS32 numRows = in->numCols;
+        psS32 numCols = in->numRows;
+        psS32 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 (psS32 row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (psS32 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);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+                psFree(out);
+                return NULL;
+            }
+        }
+    } else if (fabsf(angle - PS_PI) < FLT_EPSILON) {
+        // perform 1/2 rotate
+        psS32 numRows = in->numRows;
+        psS32 lastRow = numRows - 1;
+        psS32 numCols = in->numCols;
+        psS32 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 (psS32 row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
+                for (psS32 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);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+                psFree(out);
+                return NULL;
+            }
+        }
+    } else if (fabsf(angle - (PS_PI+PS_PI_2)) < FLT_EPSILON) {
+        // perform 1/4 rotate clockwise
+        psS32 numRows = in->numCols;
+        psS32 lastRow = numRows - 1;
+        psS32 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 (psS32 row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (psS32 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);
+                psError(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;
+        psS32 numRows = in->numRows;
+        psS32 numCols = in->numCols;
+        float centerX = (float)(numCols) / 2.0f;
+        float centerY = (float)(numRows) / 2.0f;
+        double cosT = cosf(angle);
+        double sinT = sinf(angle);
+
+        // 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;
+
+        psS32 outCols = ceil(abs(numCols * cosT) + abs(numRows * sinT)) + 1;
+        psS32 outRows = ceil(abs(numCols * sinT) + abs(numRows * cosT)) + 1;
+        float minX = (float)outCols / -2.0f;
+        psS32 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) { \
+                psError(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 (psS32 y = 0; y < outRows; y++) { \
+                inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
+                inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
+                outRow = out->data.TYPE[y]; \
+                for (psS32 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); \
+                psError(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:
+            psError(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)
+{
+    psS32 outRows;
+    psS32 outCols;
+    psS32 elementSize;
+    psElemType type;
+
+    if (in == NULL) {
+        psError(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) { \
+        psError(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 (psS32 row=0;row<outRows;row++) { \
+        ps##TYPE* outRow = out->data.TYPE[row]; \
+        float y = dy+(float)row; \
+        for (psS32 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); \
+            psError(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:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
+                mode);
+        psFree(out);
+        out = NULL;
+    }
+
+    return out;
+}
Index: /branches/rel4/psLib/src/image/psImageManip.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageManip.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageManip.h	(revision 3057)
@@ -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.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-03 21:58:53 $
+ *
+ *  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 psS32     The number of clipped pixels
+ */
+psS32 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 psS32     The number of clipped pixels
+ */
+psS32 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 psS32     The number of clipped pixels
+ */
+psS32 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 psS32         0 if success, non-zero if failed.
+ */
+psS32 psImageOverlaySection(
+    psImage* image,                    ///< target image
+    const psImage* overlay,            ///< the overlay image
+    psS32 col0,                        ///< the column to start overlay
+    psS32 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.
+    psU32 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
+    psS32 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 radians.
+    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
+    psS32 dx,                          ///< number of pixels to roll in the x-dimension
+    psS32 dy                           ///< number of pixels to roll in the y-dimension
+);
+
+#endif
Index: /branches/rel4/psLib/src/image/psImageStats.c
===================================================================
--- /branches/rel4/psLib/src/image/psImageStats.c	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageStats.c	(revision 3057)
@@ -0,0 +1,567 @@
+/** @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.63 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:10 $
+ *
+ *  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.
+/*****************************************************************************
+psImageStats(stats, in, mask, maskVal): this routine simply calls the
+psVectorStats() routine, which does the actual statistical calculation.  In
+order to do so, we create dummy psVectors and set their "data" pointer to that
+of the input psImages.
+ 
+XXX: use static psVectors
+ *****************************************************************************/
+psStats* psImageStats(psStats* stats,
+                      psImage* in,
+                      psImage* mask,
+                      psS32 maskVal)
+{
+    psVector *junkData = NULL;
+    psVector *junkMask = NULL;
+
+    PS_PTR_CHECK_NULL(stats, NULL);
+    PS_INT_CHECK_ZERO(stats->options, NULL);
+    PS_IMAGE_CHECK_NULL(in, NULL)
+    if (mask != NULL) {
+        PS_IMAGE_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+        PS_IMAGE_CHECK_SIZE_EQUAL(in, mask, NULL);
+    }
+
+    // stuff the image data into a psVector struct.
+    junkData = (psVector *) 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) {
+        // 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, NULL, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+    return (stats);
+}
+
+/*****************************************************************************
+NOTE: We assume that the psHistogram structure out has already been allocated
+and initialized.
+ *****************************************************************************/
+psHistogram* psImageHistogram(psHistogram* out,
+                              psImage* in,
+                              psImage* mask,
+                              psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(out, NULL);
+    PS_PTR_CHECK_NULL(in, NULL);
+    if (mask != NULL) {
+        PS_IMAGE_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+        PS_IMAGE_CHECK_SIZE_EQUAL(in, mask, NULL);
+    }
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    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) {
+        // 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, NULL, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+
+    return (out);
+}
+
+/*****************************************************************************
+calcScaleFactorsEval(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 scale 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.
+ 
+XXX: Use the p_psNormalizeVector here?
+ *****************************************************************************/
+double* calcScaleFactors(psS32 n)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+    psS32 i = 0;
+    double tmp = 0.0;
+    double *scalingFactors = (double *)psAlloc(n * sizeof(double));
+
+    for (i = 0; i < n; i++) {
+        tmp = (double)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((double)n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return (scalingFactors);
+}
+
+// XXX: Use a static array of Chebyshev polynomials.
+psPolynomial1D **p_psCreateChebyshevPolys(psS32 maxChebyPoly)
+{
+    PS_INT_CHECK_POSITIVE(maxChebyPoly, NULL);
+    psPolynomial1D **chebPolys = NULL;
+    psS32 i = 0;
+    psS32 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(
+chebPolys[i],
+(float) x) *
+                psPolynomial1DEval(
+chebPolys[j],
+(float) y, 
+);
+        over all pixels (x,y) in the image.
+  *****************************************************************************/
+psPolynomial2D* psImageFitPolynomial(psPolynomial2D* coeffs,
+                                     const psImage* input)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    double **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = 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 = (double **)psAlloc(coeffs->nX * sizeof(double *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (double *)psAlloc(coeffs->nY * sizeof(double));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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);
+
+    // 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++) {
+                    double pixel;
+                    if (input->type.type == PS_TYPE_S8) {
+                        pixel = (double) input->data.S8[x][y];
+                    } else if (input->type.type == PS_TYPE_U16) {
+                        pixel = (double) input->data.U16[x][y];
+                    } else if (input->type.type == PS_TYPE_F32) {
+                        pixel = (double) input->data.F32[x][y];
+                    } else if (input->type.type == PS_TYPE_F64) {
+                        pixel = input->data.F64[x][y];
+                    }
+                    sums[i][j] += pixel * psPolynomial1DEval(chebPolys[i],rScalingFactors[x]) *
+                                  psPolynomial1DEval(chebPolys[j], cScalingFactors[y]);
+                }
+            }
+        }
+    }
+
+    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] /= (double)(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);
+}
+
+
+
+
+/*****************************************************************************
+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.  This is a TEST version of the code.  It is not used by anything.
+  Input:
+  Output:
+  Internal Data Structures:
+    chebPolys[i][j] 
+    sums[i][j]: This will contain the sum of 
+                input->data.F32[x][y] *
+                psPolynomial1DEval(
+chebPolys[i],
+(float) x) *
+                psPolynomial1DEval(
+chebPolys[j],
+(float) y, 
+);
+        over all pixels (x,y) in the image.
+  *****************************************************************************/
+psPolynomial2D* psImageFitPolynomialTest(psPolynomial2D* coeffs,
+        const psImage* input)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    double **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = NULL;
+    psImage *nodes = psImageAlloc(input->numCols, input->numRows, PS_TYPE_F64);
+
+    double min = -1.0;
+    double max = 1.0;
+    double bma = 0.5 * (max-min);  // 1
+    double bpa = 0.5 * (max+min);  // 0
+    // We must calculate the value of the image at the nodes where the
+    // Chebyshev polynomials are 0.
+    for (x = 0; x < input->numRows; x++) {
+        double xTmp = cos(M_PI * (0.5 + ((float) x)) / ((float) input->numRows));
+        double xNode = - ((xTmp + bma + bpa) - 1.0);
+        double xOrig = ((float) input->numRows) * (xNode - min) / (max - min);
+
+        for (y = 0; y < input->numCols; y++) {
+            double yTmp = cos(M_PI * (0.5 + ((float) y)) / ((float) input->numCols));
+            double yNode = - ((yTmp + bma + bpa) - 1.0);
+            double yOrig = ((float) input->numCols) * (yNode - min) / (max - min);
+
+            //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yNode, xNode, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+            //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yTmp, xTmp, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yOrig, xOrig, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+        }
+    }
+
+    // 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 = (double **)psAlloc(coeffs->nX * sizeof(double *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (double *)psAlloc(coeffs->nY * sizeof(double));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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);
+
+    // 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++) {
+                    double pixel;
+                    /*
+                                        if (input->type.type == PS_TYPE_S8) {
+                                            pixel = (double) input->data.S8[x][y];
+                                        } else if (input->type.type == PS_TYPE_U16) {
+                                            pixel = (double) input->data.U16[x][y];
+                                        } else if (input->type.type == PS_TYPE_F32) {
+                                            pixel = (double) input->data.F32[x][y];
+                                        } else if (input->type.type == PS_TYPE_F64) {
+                                            pixel = input->data.F64[x][y];
+                                        }
+                    */
+                    pixel = nodes->data.F64[x][y];
+                    sums[i][j] += pixel * psPolynomial1DEval(chebPolys[i], rScalingFactors[x]) *
+                                  psPolynomial1DEval(chebPolys[j], cScalingFactors[y]);
+                }
+            }
+        }
+    }
+
+    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] /= (double)(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);
+    psFree(nodes);
+
+    return (coeffs);
+}
+
+/*****************************************************************************
+XXX: Use static variables for Chebyshev polynomials and scaling factors. 
+ *****************************************************************************/
+psImage* p_psImageEvalPolynomialCheb(psImage* input,
+                                     const psPolynomial2D* coeffs)
+{
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    // Use static data structures here.
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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(chebPolys[i], rScalingFactors[x]) *
+                        psPolynomial1DEval(chebPolys[j], cScalingFactors[y]) *
+                        coeffs->coeff[i][j];
+                }
+            }
+
+            if (input->type.type == PS_TYPE_S8) {
+                input->data.S8[x][y] = (char) polySum;
+            } else if (input->type.type == PS_TYPE_U16) {
+                input->data.U16[x][y] = (short int) polySum;
+            } else if (input->type.type == PS_TYPE_F32) {
+                input->data.F32[x][y] = (float) polySum;
+            } else if (input->type.type == PS_TYPE_F64) {
+                input->data.F64[x][y] = polySum;
+            }
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    // XXX: Use static data structures here.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return input;
+}
+
+psImage* p_psImageEvalPolynomialOrd(psImage* input,
+                                    const psPolynomial2D* coeffs)
+{
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_ORD, NULL);
+
+    for (int row = 0; row < input->numRows ; row++) {
+        for (int col = 0; col < input->numCols ; col++) {
+            if (input->type.type == PS_TYPE_S8) {
+                input->data.S8[row][col] = (psS8) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_U16) {
+                input->data.U16[row][col] = (psS16) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_F32) {
+                input->data.F32[row][col] = psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_F64) {
+                input->data.F64[row][col] = (psF64) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            }
+        }
+    }
+
+    return(input);
+}
+
+
+/*****************************************************************************
+XXX: I added normal polynomials to this routine.  Let IfA know, put it in the
+psLib SDR.
+ *****************************************************************************/
+psImage* psImageEvalPolynomial(psImage* input,
+                               const psPolynomial2D* coeffs)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+
+    if (coeffs->type == PS_POLYNOMIAL_ORD) {
+        return(p_psImageEvalPolynomialOrd(input, coeffs));
+    } else if (coeffs->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psImageEvalPolynomialCheb(input, coeffs));
+    }
+    printf("XXX: Error: wrong polynomial type\n");
+    // XXX: psError()
+    return(NULL);
+}
+
Index: /branches/rel4/psLib/src/image/psImageStats.h
===================================================================
--- /branches/rel4/psLib/src/image/psImageStats.h	(revision 3057)
+++ /branches/rel4/psLib/src/image/psImageStats.h	(revision 3057)
@@ -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 GLG, MHPCC
+*
+*  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-02 21:12:52 $
+*
+*  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)
+    psS32 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)
+    psU32 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/rel4/psLib/src/imageops/psImageConvolve.c
===================================================================
--- /branches/rel4/psLib/src/imageops/psImageConvolve.c	(revision 3057)
+++ /branches/rel4/psLib/src/imageops/psImageConvolve.c	(revision 3057)
@@ -0,0 +1,483 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-05 21:16:14 $
+ *
+ *  Copyright 2004-2005 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(psS32 xMin, psS32 xMax, psS32 yMin, psS32 yMax)
+{
+    psKernel* result;
+    psS32 numRows;
+    psS32 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);
+
+        psS32 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);
+
+        psS32 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 (psS32 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,
+                           psBool relative)
+{
+    psS32 lastX;
+    psS32 lastY;
+    psS32 lastT;
+    psS32 x;
+    psS32 y;
+    psS32 t;
+    psS32 xMin = 0;
+    psS32 xMax = 0;
+    psS32 yMin = 0;
+    psS32 yMax = 0;
+    psS32 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) {
+        psError(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);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH,
+                typeTStr, typeXStr, typeYStr);
+        return NULL;
+    }
+
+    // sizes match?
+    length = xShifts->n;
+    if (length != yShifts->n ||
+            length != tShifts->n) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "Shift vectors can not be of different sizes.");
+        return NULL;
+    }
+
+    // if no shifts, the kernel is just a 1 at 0,0
+    if (length < 1) {
+        result = psKernelAlloc(0,0,0,0);
+        result->kernel[0][0] = 1;
+        return result;
+    }
+
+    #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; \
+        lastX = xShiftData[length-1]; \
+        lastY = yShiftData[length-1]; \
+        lastT = tShiftData[length-1]; \
+        \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            x = lastX - xShiftData[lcv]; \
+            y = lastY - yShiftData[lcv]; \
+            \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        \
+        normalizeTime = 1.0 / (psKernelType)(tShiftData[length-1]); \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        psS32 prevT = 0; \
+        for (int i = 0; i < length; i++) { \
+            t = tShiftData[i] - prevT; \
+            x = lastX - xShiftData[i]; \
+            y = lastY - yShiftData[i]; \
+            \
+            kernel[y][x] += (psKernelType)t / (psKernelType)lastT; \
+            prevT = tShiftData[i]; \
+        } \
+        break; \
+    }
+
+    #define RELATIVE_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 = length-1; lcv >= 0; 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; \
+            } \
+            x -= xShiftData[lcv]; \
+            y -= yShiftData[lcv]; \
+            \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        normalizeTime = 1.0 / (psKernelType)t; \
+        x = 0; \
+        y = 0; \
+        for (psS32 i = length-1; i >= 0; i--) { \
+            kernel[y][x] += (psKernelType)(tShiftData[i]) * normalizeTime; \
+            x -= xShiftData[i]; \
+            y -= yShiftData[i]; \
+            \
+        } \
+        break; \
+    }
+
+    if (relative) {
+        switch (xShifts->type.type) {
+            RELATIVE_KERNEL_GENERATE_CASE(U8);
+            RELATIVE_KERNEL_GENERATE_CASE(U16);
+            RELATIVE_KERNEL_GENERATE_CASE(U32);
+            RELATIVE_KERNEL_GENERATE_CASE(U64);
+            RELATIVE_KERNEL_GENERATE_CASE(S8);
+            RELATIVE_KERNEL_GENERATE_CASE(S16);
+            RELATIVE_KERNEL_GENERATE_CASE(S32);
+            RELATIVE_KERNEL_GENERATE_CASE(S64);
+            RELATIVE_KERNEL_GENERATE_CASE(F32);
+            RELATIVE_KERNEL_GENERATE_CASE(F64);
+            RELATIVE_KERNEL_GENERATE_CASE(C32);
+            RELATIVE_KERNEL_GENERATE_CASE(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,xShifts->type.type);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+            }
+        }
+    } else {
+        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);
+                psError(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, psBool direct)
+{
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if (kernel == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImageConvolve_KERNEL_NULL);
+        psFree(out);
+        return NULL;
+    }
+    psS32 xMin = kernel->xMin;
+    psS32 xMax = kernel->xMax;
+    psS32 yMin = kernel->yMin;
+    psS32 yMax = kernel->yMax;
+    psKernelType** kData = kernel->kernel;
+
+    // make the output image to the proper size and type
+    psS32 numRows = in->numRows;
+    psS32 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 (psS32 row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (psS32 col=0;col<numCols;col++) { \
+                    ps##TYPE pixel = 0.0; \
+                    for (psS32 kRow = yMin; kRow < yMax; kRow++) { \
+                        if (row-kRow >= 0 && row-kRow < numRows) { \
+                            for (psS32 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);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+                psFree(out);
+                return NULL;
+
+            }
+        }
+
+
+    } else {
+        // fourier convolution
+        psS32 paddedCols = numCols+2*FOURIER_PADDING;
+        psS32 paddedRows = numRows+2*FOURIER_PADDING;
+
+        // check to see if kernel is smaller, otherwise padding it up will fail.
+        psS32 kRows = kernel->image->numRows;
+        psS32 kCols = kernel->image->numCols;
+        if (kRows >= numRows || kCols >= numCols) {
+            psError(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);
+        psS32 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.
+        psS32 sidePaddingSize = FOURIER_PADDING*elementSize;
+        psS32 imageRowSize = numCols*elementSize;
+        psU8* paddedData = paddedImage->data.U8[FOURIER_PADDING];
+        for (psS32 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
+        psS32 yMax = kernel->yMax;
+        psS32 xMax = kernel->xMax;
+        for (psS32 row = kernel->yMin; row <= yMax;row++) {
+            psS32 padRow = row;
+            if (padRow < 0) {
+                padRow += paddedRows;
+            }
+            psKernelType* padData = paddedKernel->data.PS_TYPE_KERNEL_DATA[padRow];
+            psKernelType* kernelRow = kernel->kernel[row];
+            for (psS32 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) {
+            psError(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) {
+            psError(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) {
+            psError(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 (psS32 row = 0; row < numRows; row++) {
+            psF32* outRow = out->data.F32[row];
+            psC32* resultRow = complexOutSansPad->data.C32[row];
+            for (psS32 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/rel4/psLib/src/imageops/psImageConvolve.h
===================================================================
--- /branches/rel4/psLib/src/imageops/psImageConvolve.h	(revision 3057)
+++ /branches/rel4/psLib/src/imageops/psImageConvolve.h	(revision 3057)
@@ -0,0 +1,121 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_CONVOLVE_H
+#define PS_IMAGE_CONVOLVE_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
+    psS32 xMin;                          ///< Most negative x index
+    psS32 yMin;                          ///< Most negative y index
+    psS32 xMax;                          ///< Most positive x index
+    psS32 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(
+    psS32 xMin,                          ///< Most negative x index
+    psS32 xMax,                          ///< Most positive x index
+    psS32 yMin,                          ///< Most negative y index
+    psS32 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
+    psBool 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
+    psBool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /branches/rel4/psLib/src/imageops/psImageStats.c
===================================================================
--- /branches/rel4/psLib/src/imageops/psImageStats.c	(revision 3057)
+++ /branches/rel4/psLib/src/imageops/psImageStats.c	(revision 3057)
@@ -0,0 +1,567 @@
+/** @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.63 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:10 $
+ *
+ *  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.
+/*****************************************************************************
+psImageStats(stats, in, mask, maskVal): this routine simply calls the
+psVectorStats() routine, which does the actual statistical calculation.  In
+order to do so, we create dummy psVectors and set their "data" pointer to that
+of the input psImages.
+ 
+XXX: use static psVectors
+ *****************************************************************************/
+psStats* psImageStats(psStats* stats,
+                      psImage* in,
+                      psImage* mask,
+                      psS32 maskVal)
+{
+    psVector *junkData = NULL;
+    psVector *junkMask = NULL;
+
+    PS_PTR_CHECK_NULL(stats, NULL);
+    PS_INT_CHECK_ZERO(stats->options, NULL);
+    PS_IMAGE_CHECK_NULL(in, NULL)
+    if (mask != NULL) {
+        PS_IMAGE_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+        PS_IMAGE_CHECK_SIZE_EQUAL(in, mask, NULL);
+    }
+
+    // stuff the image data into a psVector struct.
+    junkData = (psVector *) 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) {
+        // 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, NULL, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+    return (stats);
+}
+
+/*****************************************************************************
+NOTE: We assume that the psHistogram structure out has already been allocated
+and initialized.
+ *****************************************************************************/
+psHistogram* psImageHistogram(psHistogram* out,
+                              psImage* in,
+                              psImage* mask,
+                              psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(out, NULL);
+    PS_PTR_CHECK_NULL(in, NULL);
+    if (mask != NULL) {
+        PS_IMAGE_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+        PS_IMAGE_CHECK_SIZE_EQUAL(in, mask, NULL);
+    }
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    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) {
+        // 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, NULL, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+
+    return (out);
+}
+
+/*****************************************************************************
+calcScaleFactorsEval(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 scale 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.
+ 
+XXX: Use the p_psNormalizeVector here?
+ *****************************************************************************/
+double* calcScaleFactors(psS32 n)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+    psS32 i = 0;
+    double tmp = 0.0;
+    double *scalingFactors = (double *)psAlloc(n * sizeof(double));
+
+    for (i = 0; i < n; i++) {
+        tmp = (double)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((double)n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return (scalingFactors);
+}
+
+// XXX: Use a static array of Chebyshev polynomials.
+psPolynomial1D **p_psCreateChebyshevPolys(psS32 maxChebyPoly)
+{
+    PS_INT_CHECK_POSITIVE(maxChebyPoly, NULL);
+    psPolynomial1D **chebPolys = NULL;
+    psS32 i = 0;
+    psS32 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(
+chebPolys[i],
+(float) x) *
+                psPolynomial1DEval(
+chebPolys[j],
+(float) y, 
+);
+        over all pixels (x,y) in the image.
+  *****************************************************************************/
+psPolynomial2D* psImageFitPolynomial(psPolynomial2D* coeffs,
+                                     const psImage* input)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    double **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = 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 = (double **)psAlloc(coeffs->nX * sizeof(double *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (double *)psAlloc(coeffs->nY * sizeof(double));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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);
+
+    // 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++) {
+                    double pixel;
+                    if (input->type.type == PS_TYPE_S8) {
+                        pixel = (double) input->data.S8[x][y];
+                    } else if (input->type.type == PS_TYPE_U16) {
+                        pixel = (double) input->data.U16[x][y];
+                    } else if (input->type.type == PS_TYPE_F32) {
+                        pixel = (double) input->data.F32[x][y];
+                    } else if (input->type.type == PS_TYPE_F64) {
+                        pixel = input->data.F64[x][y];
+                    }
+                    sums[i][j] += pixel * psPolynomial1DEval(chebPolys[i],rScalingFactors[x]) *
+                                  psPolynomial1DEval(chebPolys[j], cScalingFactors[y]);
+                }
+            }
+        }
+    }
+
+    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] /= (double)(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);
+}
+
+
+
+
+/*****************************************************************************
+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.  This is a TEST version of the code.  It is not used by anything.
+  Input:
+  Output:
+  Internal Data Structures:
+    chebPolys[i][j] 
+    sums[i][j]: This will contain the sum of 
+                input->data.F32[x][y] *
+                psPolynomial1DEval(
+chebPolys[i],
+(float) x) *
+                psPolynomial1DEval(
+chebPolys[j],
+(float) y, 
+);
+        over all pixels (x,y) in the image.
+  *****************************************************************************/
+psPolynomial2D* psImageFitPolynomialTest(psPolynomial2D* coeffs,
+        const psImage* input)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    double **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = NULL;
+    psImage *nodes = psImageAlloc(input->numCols, input->numRows, PS_TYPE_F64);
+
+    double min = -1.0;
+    double max = 1.0;
+    double bma = 0.5 * (max-min);  // 1
+    double bpa = 0.5 * (max+min);  // 0
+    // We must calculate the value of the image at the nodes where the
+    // Chebyshev polynomials are 0.
+    for (x = 0; x < input->numRows; x++) {
+        double xTmp = cos(M_PI * (0.5 + ((float) x)) / ((float) input->numRows));
+        double xNode = - ((xTmp + bma + bpa) - 1.0);
+        double xOrig = ((float) input->numRows) * (xNode - min) / (max - min);
+
+        for (y = 0; y < input->numCols; y++) {
+            double yTmp = cos(M_PI * (0.5 + ((float) y)) / ((float) input->numCols));
+            double yNode = - ((yTmp + bma + bpa) - 1.0);
+            double yOrig = ((float) input->numCols) * (yNode - min) / (max - min);
+
+            //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yNode, xNode, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+            //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yTmp, xTmp, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yOrig, xOrig, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+        }
+    }
+
+    // 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 = (double **)psAlloc(coeffs->nX * sizeof(double *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (double *)psAlloc(coeffs->nY * sizeof(double));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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);
+
+    // 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++) {
+                    double pixel;
+                    /*
+                                        if (input->type.type == PS_TYPE_S8) {
+                                            pixel = (double) input->data.S8[x][y];
+                                        } else if (input->type.type == PS_TYPE_U16) {
+                                            pixel = (double) input->data.U16[x][y];
+                                        } else if (input->type.type == PS_TYPE_F32) {
+                                            pixel = (double) input->data.F32[x][y];
+                                        } else if (input->type.type == PS_TYPE_F64) {
+                                            pixel = input->data.F64[x][y];
+                                        }
+                    */
+                    pixel = nodes->data.F64[x][y];
+                    sums[i][j] += pixel * psPolynomial1DEval(chebPolys[i], rScalingFactors[x]) *
+                                  psPolynomial1DEval(chebPolys[j], cScalingFactors[y]);
+                }
+            }
+        }
+    }
+
+    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] /= (double)(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);
+    psFree(nodes);
+
+    return (coeffs);
+}
+
+/*****************************************************************************
+XXX: Use static variables for Chebyshev polynomials and scaling factors. 
+ *****************************************************************************/
+psImage* p_psImageEvalPolynomialCheb(psImage* input,
+                                     const psPolynomial2D* coeffs)
+{
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_CHEB, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 maxChebyPoly = 0;
+    double *cScalingFactors = NULL;
+    double *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    // Use static data structures here.
+    rScalingFactors = calcScaleFactors(input->numRows);
+    cScalingFactors = calcScaleFactors(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(chebPolys[i], rScalingFactors[x]) *
+                        psPolynomial1DEval(chebPolys[j], cScalingFactors[y]) *
+                        coeffs->coeff[i][j];
+                }
+            }
+
+            if (input->type.type == PS_TYPE_S8) {
+                input->data.S8[x][y] = (char) polySum;
+            } else if (input->type.type == PS_TYPE_U16) {
+                input->data.U16[x][y] = (short int) polySum;
+            } else if (input->type.type == PS_TYPE_F32) {
+                input->data.F32[x][y] = (float) polySum;
+            } else if (input->type.type == PS_TYPE_F64) {
+                input->data.F64[x][y] = polySum;
+            }
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    // XXX: Use static data structures here.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return input;
+}
+
+psImage* p_psImageEvalPolynomialOrd(psImage* input,
+                                    const psPolynomial2D* coeffs)
+{
+    PS_POLY_CHECK_TYPE(coeffs, PS_POLYNOMIAL_ORD, NULL);
+
+    for (int row = 0; row < input->numRows ; row++) {
+        for (int col = 0; col < input->numCols ; col++) {
+            if (input->type.type == PS_TYPE_S8) {
+                input->data.S8[row][col] = (psS8) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_U16) {
+                input->data.U16[row][col] = (psS16) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_F32) {
+                input->data.F32[row][col] = psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            } else if (input->type.type == PS_TYPE_F64) {
+                input->data.F64[row][col] = (psF64) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+            }
+        }
+    }
+
+    return(input);
+}
+
+
+/*****************************************************************************
+XXX: I added normal polynomials to this routine.  Let IfA know, put it in the
+psLib SDR.
+ *****************************************************************************/
+psImage* psImageEvalPolynomial(psImage* input,
+                               const psPolynomial2D* coeffs)
+{
+    PS_IMAGE_CHECK_NULL(input, NULL);
+    PS_IMAGE_CHECK_EMPTY(input, NULL);
+    if ((input->type.type != PS_TYPE_S8) &&
+            (input->type.type != PS_TYPE_U16) &&
+            (input->type.type != PS_TYPE_F32) &&
+            (input->type.type != PS_TYPE_F64)) {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                "Unallowable image type.\n");
+    }
+    PS_POLY_CHECK_NULL(coeffs, NULL);
+
+    if (coeffs->type == PS_POLYNOMIAL_ORD) {
+        return(p_psImageEvalPolynomialOrd(input, coeffs));
+    } else if (coeffs->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psImageEvalPolynomialCheb(input, coeffs));
+    }
+    printf("XXX: Error: wrong polynomial type\n");
+    // XXX: psError()
+    return(NULL);
+}
+
Index: /branches/rel4/psLib/src/imageops/psImageStats.h
===================================================================
--- /branches/rel4/psLib/src/imageops/psImageStats.h	(revision 3057)
+++ /branches/rel4/psLib/src/imageops/psImageStats.h	(revision 3057)
@@ -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 GLG, MHPCC
+*
+*  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-02 21:12:52 $
+*
+*  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)
+    psS32 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)
+    psU32 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/rel4/psLib/src/mainpage.dox
===================================================================
--- /branches/rel4/psLib/src/mainpage.dox	(revision 3057)
+++ /branches/rel4/psLib/src/mainpage.dox	(revision 3057)
@@ -0,0 +1,178 @@
+/** @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
+ - 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, with single-precison float support
+     - Available at http://www.fftw.org
+     - Compatibility tested with version is 3.0.1
+     - The '--enable-float' option is required in the configure step to enable single-precision float support.  Use 'configure --help' for more information of the configuration options for this library.
+ - 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 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.
+ - Gnome XML C parser and toolkit (libxml2)
+     - Available at http://www.xmlsoft.org
+     - Compatibility tested with version 2-2.6.16-3
+
+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, rel3, or rel4.
+
+
+@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>
+
+The make system of psLib allows users to specify specific locations for some of the
+third party libraries (see "Required 3rd Party Libraries" for a list).  If
+a location is not specified, the cooresponding library is assumed to be in
+the standard library paths, e.g., /usr or /usr/local.  The following are the
+environment variables that can be set before the make process above to force
+the location of the third-party libraries:
+  - sladir: Location of SLALIB
+      - e.g., <pre>export sladir=/usr/local/star</pre>
+  - xml2config: Location of the xml2-config configuration executable
+      - e.g., <pre>export xml2config=/usr/bin/xml2-config</pre>
+
+Also, the installation location of the library can be set using environment
+variables.  The following are the supported variables for installation:
+  - prefix: the installation prefix (default: current psLib directory)
+      - e.g., <pre>export prefix=/usr/local</pre>
+  - mandir: The man page installation location (default: $prefix/man)
+  - includedir: The installation location for the header files (default: $prefix/include)
+  - testbindir: Location for the test executables (default: $prefix/testbin)
+  - libexecdir: Location for the library files (default: $prefix/lib)
+  - TIME_CONFIG_FILE: Location of the 'psTime.config' configuration file (default: $(prefix)/config/psTime.config)
+
+@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/rel4/psLib/src/math/psCompare.c
===================================================================
--- /branches/rel4/psLib/src/math/psCompare.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psCompare.c	(revision 3057)
@@ -0,0 +1,79 @@
+
+/** @file psCompare.c
+ *  @brief Comparison functions for sorting routines
+ *  @ingroup Compare
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#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/rel4/psLib/src/math/psCompare.h
===================================================================
--- /branches/rel4/psLib/src/math/psCompare.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psCompare.h	(revision 3057)
@@ -0,0 +1,508 @@
+/** @file psCompare.h
+ *  @brief Comparison functions for sorting routines
+ *
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup Compare
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_COMPARE_H)
+#define PS_COMPARE_H
+
+#include "psType.h"
+
+/** @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/rel4/psLib/src/math/psConstants.h
===================================================================
--- /branches/rel4/psLib/src/math/psConstants.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psConstants.h	(revision 3057)
@@ -0,0 +1,636 @@
+/** @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.53 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-10 19:47:11 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: Add parenthesis around all arguments so that these macros can be
+ *       called with complex expressions.
+ *
+ *
+ *
+ */
+
+/*****************************************************************************
+These constants are used by various functions in the psLib.
+ *****************************************************************************/
+#define PS_DETERMINE_BRACKET_STEP_SIZE 0.10
+#define PS_MAX_LMM_ITERATIONS 100
+#define PS_MAX_MINIMIZE_ITERATIONS 100
+#define PS_LEFT_SPLINE_DERIV 0.0
+#define PS_RIGHT_SPLINE_DERIV 0.0
+/*****************************************************************************
+These are common mathimatical constants used by various functions in the psLib.
+ *****************************************************************************/
+#define PS_ONE 1.0
+#define PS_PI   3.1415926535897932384626433832795029  /* pi */
+#define PS_PI_2 1.5707963267948966192313216916397514  /* pi/2 */
+#define PS_PI_4 0.7853981633974483096156608458198757  /* pi/4 */
+#define PS_1_PI 0.3183098861837906715377675267450287  /* 1/pi */
+#define PS_2_PI 0.6366197723675813430755350534900574  /* 2/pi */
+
+#define PS_COT(X) (1.0 / atan(X))
+#define DEG_TO_RAD(DEGREES) ((DEGREES) * M_PI / 180.0)
+#define MIN_TO_RAD(MINUTES) ((MINUTES) * M_PI / (180.0 * 60.0))
+#define SEC_TO_RAD(SECONDS) ((SECONDS) * M_PI / (180.0 * 60.0 * 60.0))
+#define RAD_TO_DEG(RADIANS) ((RADIANS) * 180.0 / M_PI)
+#define RAD_TO_MIN(RADIANS) ((RADIANS) * 180.0 * 60.0 / M_PI)
+#define RAD_TO_SEC(RADIANS) ((RADIANS) * 180.0 * 60.0 * 60.0 / M_PI)
+
+/*****************************************************************************
+ 
+*****************************************************************************/
+
+#define PS_INT_CHECK_EQUALS(NAME1, NAME2, RVAL) \
+if (NAME1 == NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_NON_EQUALS(NAME1, NAME2, RVAL) \
+if (NAME1 != NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are not equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_NON_NEGATIVE(NAME, RVAL) \
+if (NAME < 0) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is less than 0.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_POSITIVE(NAME, RVAL) \
+if (NAME < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is 0 or less.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_ZERO(NAME, RVAL) \
+if (NAME < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s is 0.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_INT_CHECK_RANGE(NAME, LOWER, UPPER, RVAL) \
+if ((int)NAME < LOWER || (int)NAME > UPPER) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s, %d, is out of range.  Must be between %d and %d.", \
+            #NAME,(int)NAME,LOWER,UPPER); \
+    return RVAL; \
+}
+
+// Produce an error if (NAME1 > NAME2)
+#define PS_INT_COMPARE(NAME1, NAME2, RVAL) \
+if (NAME1 > NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: (%s > %s) (%d %d).", \
+            #NAME1, #NAME2, NAME1, NAME2); \
+    return(RVAL); \
+}
+
+
+// Produce an error if ((NAME1 > NAME2)
+#define PS_FLOAT_COMPARE(NAME1, NAME2, RVAL) \
+if (NAME1 > NAME2) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: (%s > %s) (%f %f)", \
+            #NAME1, #NAME2, NAME1, NAME2); \
+    return(RVAL); \
+}
+
+#define PS_FLOAT_CHECK_NON_EQUAL(NAME1, NAME2, RVAL) \
+if (fabs(NAME2 - NAME1) < FLT_EPSILON) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s and %s are equal.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_FLOAT_CHECK_RANGE(NAME, LOWER, UPPER, RVAL) \
+if ((NAME) < (LOWER) || (NAME) > (UPPER)) { \
+    psError(PS_ERR_BAD_PARAMETER_VALUE, true, \
+            "Error: %s, %f, is out of range.  Must be between %f and %f.", \
+            #NAME, NAME, LOWER, UPPER); \
+    return RVAL; \
+}
+
+/*****************************************************************************
+Macros which take a generic psLib type and determine if it is NULL, or has
+the wrong type.
+*****************************************************************************/
+#define PS_PTR_CHECK_NULL(NAME, RVAL) PS_PTR_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_PTR_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: %s is NULL.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_PTR_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_PTR_CHECK_DIMEN(NAME, DIMEN, RVAL) PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, return RVAL)
+#define PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, CLEANUP) \
+if (NAME->type.dimen != DIMEN) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect dimensionality.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_PTR_CHECK_DIMEN_GENERAL_NOT(NAME, DIMEN, CLEANUP) \
+if (NAME->type.dimen == DIMEN) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: %s has incorrect dimensionality.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+
+#define PS_PTR_CHECK_SIZE_EQUAL(PTR1, PTR2, RVAL) \
+if (PTR1->n != PTR2->n) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "ptr %s has size %d, ptr %s has size %d.", \
+            #PTR1, PTR1->n, #PTR2, PTR2->n); \
+    return(RVAL); \
+}
+
+#define PS_PTR_CHECK_TYPE_EQUAL(PTR1, PTR2, RVAL) PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, return RVAL)
+
+#define PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, CLEANUP) \
+if (PTR1->type.type != PTR2->type.type) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "ptr %s has type %d, ptr %s has type %d.", \
+            #PTR1, PTR1->type.type, #PTR2, PTR2->type.type); \
+    CLEANUP; \
+}
+
+
+/*****************************************************************************
+    PS_VECTOR macros:
+ *****************************************************************************/
+#define PS_VECTOR_CHECK_NULL(NAME, RVAL) PS_VECTOR_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_VECTOR_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psVector %s or its data is NULL.", \
+            #NAME); \
+    CLEANUP; \
+} \
+
+#define PS_VECTOR_CHECK_EMPTY(NAME, RVAL) \
+if (NAME->n < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psVector %s has no elements.", \
+            #NAME); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE_F32_OR_F64(NAME, RVAL) \
+if ((NAME->type.type != PS_TYPE_F32) && (NAME->type.type != PS_TYPE_F64)) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "psVector %s: bad type(%d)", \
+            #NAME, NAME->type.type); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE_S16_S32_F32(NAME, RVAL) \
+if ((NAME->type.type != PS_TYPE_S16) && (NAME->type.type != PS_TYPE_S32) && (NAME->type.type != PS_TYPE_F32)) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "psVector %s: bad type(%d)", \
+            #NAME, NAME->type.type); \
+    return(RVAL); \
+} \
+
+#define PS_VECTOR_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psVector %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_VECTOR_CHECK_SIZE_EQUAL(VEC1, VEC2, RVAL) \
+if (VEC1->n != VEC2->n) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "psVector %s has size %d, psVector %s has size %d.", \
+            #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(RVAL); \
+}
+
+#define PS_VECTOR_CHECK_TYPE_EQUAL(VEC1, VEC2, RVAL) \
+if (VEC1->type.type != VEC2->type.type) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "psVector %s has size %d, psVector %s has size %d.", \
+            #VEC1, VEC1->type.type, #VEC2, VEC2->type.type); \
+    return(RVAL); \
+}
+
+#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_VECTOR_PRINT_F32(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_CONVERT_F64_TO_F32_STATIC(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 PS_VECTOR_CONVERT_F32_TO_F64_STATIC(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 PS_VECTOR_GEN_YERR_STATIC_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 PS_VECTOR_GEN_YERR_STATIC_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 PS_VECTOR_GEN_X_INDEX_STATIC_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 PS_VECTOR_GEN_X_INDEX_STATIC_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 PS_VECTOR_GEN_STATIC_RECYCLED(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+NAME = psVectorRecycle(NAME, SIZE, TYPE); \
+p_psMemSetPersistent(NAME, true); \
+p_psMemSetPersistent(NAME->data.V, true); \
+
+#define PS_VECTOR_DECLARE_ALLOC_STATIC(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psVectorAlloc(SIZE, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_VECTOR_SET_U8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U8[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U16[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U32[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_U64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.U64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S8[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S16[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S32[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_S64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.S64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_F64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.F64[i] = VALUE; \
+}\
+
+#define PS_VECTOR_SET_F32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->n ; i++) { \
+    (NAME)->data.F32[i] = VALUE; \
+}\
+
+
+/*****************************************************************************
+    PS_POLY macros:
+*****************************************************************************/
+#define PS_POLY_CHECK_NULL(NAME, RVAL) \
+if (NAME == NULL || NAME->coeff == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: polynomial %s or its coeffs is NULL.", \
+            #NAME); \
+    return(RVAL); \
+} \
+
+#define PS_POLY_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: polynomial %s has wrong type.", #NAME); \
+    return(RVAL); \
+} \
+
+// The following macros declare and allocate a static polynomial of the
+// specified order and type.
+
+#define PS_POLY_1D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial1D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial1DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+    p_psMemSetPersistent(NAME->coeff, true); \
+    p_psMemSetPersistent(NAME->coeffErr, true); \
+    p_psMemSetPersistent(NAME->mask, true); \
+} \
+
+#define PS_POLY_2D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial2D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial2DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_3D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial3D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial3DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_4D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial4D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial4DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_1D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial1D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial1DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_2D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial2D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial2DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_3D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial3D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial3DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+#define PS_POLY_4D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \
+static psPolynomial4D *NAME = NULL; \
+if (NAME == NULL) { \
+    NAME = psPolynomial4DAlloc(ORDER, TYPE); \
+    p_psMemSetPersistent(NAME, true); \
+} \
+
+/*****************************************************************************
+    PS_IMAGE macros:
+*****************************************************************************/
+#define PS_IMAGE_CHECK_NULL(NAME, RVAL) PS_IMAGE_CHECK_NULL_GENERAL(NAME, return RVAL)
+#define PS_IMAGE_CHECK_NULL_GENERAL(NAME, CLEANUP) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psImage %s or its data is NULL.", \
+            #NAME); \
+    CLEANUP; \
+}
+
+#define PS_IMAGE_CHECK_EMPTY(NAME, RVAL) PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, return RVAL)
+#define PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, CLEANUP) \
+if (NAME->numCols < 1 || NAME->numRows < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImage %s has zero rows or columns (%dx%d).", \
+            #NAME, NAME->numCols, NAME->numRows); \
+    CLEANUP; \
+}
+
+#define PS_IMAGE_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psImage %s has incorrect type.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_CHECK_SIZE_EQUAL(NAME1, NAME2, RVAL) \
+if ((NAME1->numCols != NAME2->numCols) || \
+        (NAME1->numRows != NAME2->numRows)) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImages %s and %s are not the same size.", \
+            #NAME1, #NAME2); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_CHECK_SIZE(NAME1, NUM_COLS, NUM_ROWS, RVAL) \
+if ((NAME1->numCols != NUM_COLS) || \
+        (NAME1->numRows != NUM_ROWS)) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psImages %s is not the correct size.", \
+            #NAME1); \
+    return(RVAL); \
+}
+
+#define PS_IMAGE_PRINT_F32(NAME) \
+printf("======== printing %s ========\n", #NAME); \
+for (int i = 0 ; i < NAME->numRows ; i++) { \
+    for (int j = 0 ; j < NAME->numCols ; j++) { \
+        printf("%.2f ", NAME->data.F32[i][j]); \
+    } \
+    printf("\n"); \
+}\
+
+#define PS_IMAGE_SET_U8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U8[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U16[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_U64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.U64[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S8(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S8[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S16(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S16[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_S64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.S64[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_F32(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.F32[i][j] = (VALUE); \
+    } \
+}\
+
+#define PS_IMAGE_SET_F64(NAME, VALUE) \
+for (int i = 0 ; i < (NAME)->numRows ; i++) { \
+    for (int j = 0 ; j < (NAME)->numCols ; j++) { \
+        (NAME)->data.F64[i][j] = (VALUE); \
+    } \
+}\
+
+/*****************************************************************************
+    PS_READOUT macros:
+*****************************************************************************/
+#define PS_READOUT_CHECK_NULL(NAME, RVAL) \
+if (NAME == NULL || NAME->image == NULL) { \
+    psError(PS_ERR_BAD_PARAMETER_NULL, true, \
+            "Unallowable operation: psReadout %s or its data is NULL.", \
+            #NAME); \
+    return(RVAL); \
+}
+
+#define PS_READOUT_CHECK_EMPTY(NAME, RVAL) \
+if (NAME->image->numCols < 1 || NAME->image->numRows < 1) { \
+    psError(PS_ERR_BAD_PARAMETER_SIZE, true, \
+            "Unallowable operation: psReadout %s or its data is NULL.", #NAME); \
+    return(RVAL); \
+}
+
+#define PS_READOUT_CHECK_TYPE(NAME, TYPE, RVAL) \
+if (NAME->image->type.type != TYPE) { \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, \
+            "Unallowable operation: psImage %s has incorrect type.", #NAME); \
+    return(RVAL); \
+}
+
+/*****************************************************************************
+    Misc. macros:
+ *****************************************************************************/
+#define PS_MAX(A, B) \
+(((A) > (B)) ? (A) : (B)) \
+
+#define PS_MIN(A, B) \
+(((A) < (B)) ? (A) : (B)) \
+
+#define PS_SQR(A) \
+((A) * (A)) \
+
+#ifdef DARWIN
+#define PS_SQRT_F32(A) ((float) sqrt(A))
+#else
+#define PS_SQRT_F32(A) (sqrtf(A))
+#endif
Index: /branches/rel4/psLib/src/math/psMatrix.c
===================================================================
--- /branches/rel4/psLib/src/math/psMatrix.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psMatrix.c	(revision 3057)
@@ -0,0 +1,626 @@
+/** @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.22 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 22:17:29 $
+ *
+ *  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"
+#include "psConstants.h"
+#include "psDataManipErrors.h"
+
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/** 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(PS_ERR_BAD_PARAMETER_TYPE, true,                                                        \
+            "Invalid operation. %s has incorrect dimensionality %d.", #NAME, PS_DIMEN);             \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type!=PS_TYPE_F64 && NAME->type.type!=PS_TYPE_F32) {                           \
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true,                                                        \
+            "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(PS_ERR_BAD_PARAMETER_VALUE, true,                                                       \
+            "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(PS_ERR_BAD_PARAMETER_SIZE, true, "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;
+
+
+/*****************************************************************************/
+/* FILE STATIC FUNCTIONS                                                     */
+/*****************************************************************************/
+
+static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector);
+static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector);
+static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage);
+static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix);
+
+/** Static function to copy psF32 or psF64 vector data to a GSL vector */
+static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector)
+{
+    psU32 i = 0;
+    psU32 n = 0;
+
+
+    n = inVector->n;
+    for(i=0; i<n; i++) {
+        if(inVector->type.type == PS_TYPE_F32) {
+            outGslVector->data[i] = (psF64)inVector->data.F32[i];
+        } else {
+            outGslVector->data[i] = inVector->data.F64[i];
+        }
+    }
+}
+
+/** Static function to copy GSL vector data to a psF32 or psF64 vector */
+static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector)
+{
+    psU32 i = 0;
+    psU32 n = 0;
+
+
+    n = outVector->n;
+    for(i=0; i<n; i++) {
+        if(outVector->type.type == PS_TYPE_F32) {
+            outVector->data.F32[i] = (psF32)inGslVector->data[i];
+        } else {
+            outVector->data.F64[i] = inGslVector->data[i];
+        }
+    }
+}
+
+/** Static function to copy psF32 or psF64 image data to a GSL matrix */
+static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psU32 numRows = 0;
+    psU32 numCols = 0;
+
+
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    for(i=0; i<numRows; i++) {
+        for(j=0; j<numCols; j++) {
+            if(inImage->type.type == PS_TYPE_F32) {
+                outGslMatrix->data[i*numCols+j] = (psF64)inImage->data.F32[i][j];
+            } else {
+                outGslMatrix->data[i*numCols+j] = inImage->data.F64[i][j];
+            }
+        }
+    }
+}
+
+/** Static function to copy GSL matrix data to a psF32 or psF64 image */
+static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psU32 numRows = 0;
+    psU32 numCols = 0;
+
+
+    numRows = outImage->numRows;
+    numCols = outImage->numCols;
+    for(i=0; i<numRows; i++) {
+        for(j=0; j<numCols; j++) {
+            if(outImage->type.type == PS_TYPE_F32) {
+                outImage->data.F32[i][j] = (psF32)inGslMatrix->data[i*numCols+j];
+            } else {
+                outImage->data.F64[i][j] = inGslMatrix->data[i*numCols+j];
+            }
+        }
+    }
+}
+
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage* psMatrixLUD(psImage* outImage, psVector** outPerm, psImage* inImage)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *lu = NULL;
+    gsl_permutation perm;
+
+
+    #define psMatrixLUD_EXIT {psFree(outImage); return NULL;}
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL_GENERAL(inImage, psMatrixLUD_EXIT);
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_PTR_CHECK_NULL_GENERAL(outPerm, psMatrixLUD_EXIT);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    if (sizeof(size_t) == 4) {
+        *outPerm = psVectorRecycle(*outPerm, numCols, PS_TYPE_S32);
+    } else if (sizeof(size_t) == 8) {
+        *outPerm = psVectorRecycle(*outPerm, numCols, PS_TYPE_S64);
+    } else {
+        psError(PS_ERR_UNKNOWN, true,
+                "Failed to allocate the permutation vector; "
+                "could not determine the cooresponding data type.");
+        psMatrixLUD_EXIT;
+    }
+
+    (*outPerm)->n = numCols;
+    perm.data = (*outPerm)->data.V;
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Copy psImage data into GSL matrix data
+    psImageToGslMatrix(lu, inImage);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(lu, &perm, &signum);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, lu);
+
+    // Free GSL data
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, const psVector* inVector,
+                          const psVector* inPerm)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *lu;
+    gsl_permutation perm;
+    gsl_vector *b = NULL;
+    gsl_vector *x = NULL;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_IMAGE_CHECK_NULL(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_IMAGE_CHECK_EMPTY(inImage, outVector);
+    PS_VECTOR_CHECK_NULL(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_VECTOR_CHECK_NULL(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_VECTOR_CHECK_NULL(inPerm, outVector);
+    psVectorRecycle(outVector, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    lu = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+    b = gsl_vector_alloc(inVector->n);
+    psVectorToGslVector(b, inVector);
+    x = gsl_vector_alloc(inVector->n);
+
+    outVector->n = numCols;
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(lu, &perm, b, x);
+
+    // Copy GSL vector data to psVector data
+    gslVectorToPsVector(outVector, x);
+
+    // Free GSL data
+    gsl_vector_free(b);
+    gsl_vector_free(x);
+    gsl_matrix_free(lu);
+
+    return outVector;
+}
+
+psImage* psMatrixInvert(psImage* outImage, const psImage* inImage, psF32 *det)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *inv = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_PTR_CHECK_NULL(det, outImage);
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+    inv = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+
+    // 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);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, inv);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+    gsl_matrix_free(inv);
+
+    return outImage;
+}
+
+psF32 *psMatrixDeterminant(const psImage* inImage)
+{
+    psS32 signum = 0;
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    psF32 *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_IMAGE_CHECK_EMPTY(inImage, NULL);
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(lu, inImage);
+
+    // Calculate determinant
+    det = (psF32*)psAlloc(sizeof(psF32));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (psF32)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)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_matrix *m1 = NULL;
+    gsl_matrix *m2 = NULL;
+    gsl_matrix *m3 = NULL;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_IMAGE_CHECK_NULL(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage1, outImage);
+    PS_IMAGE_CHECK_NULL(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    psImageRecycle(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+
+    // Initialize GSL data
+    m1 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m1, inImage1);
+    m2 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m2, inImage2);
+    m3 = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(m3, outImage);
+
+    // Perform multiplication
+    gsl_linalg_matmult(m1, m2, m3);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, m3);
+
+    // Free GSL structs
+    gsl_matrix_free(m1);
+    gsl_matrix_free(m2);
+    gsl_matrix_free(m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage* outImage, const psImage* inImage)
+{
+    psU32 i = 0;
+    psU32 j = 0;
+    psS32 numRowsIn = 0;
+    psS32 numColsIn = 0;
+    psS32 numRowsOut = 0;
+    psS32 numColsOut = 0;
+
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    outImage = psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRowsIn = inImage->numRows;
+    numColsIn = inImage->numCols;
+    numRowsOut = outImage->numRows;
+    numColsOut = outImage->numCols;
+
+    if(numRowsIn!=numColsOut && numRowsOut!=numColsIn) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH);
+    }
+
+    if(outImage->type.type == PS_TYPE_F32) {
+        for(i=0; i<numRowsOut; i++) {
+            for(j=0; j<numColsOut; j++) {
+                outImage->data.F32[i][j] = inImage->data.F32[j][i];
+            }
+        }
+    } else {
+        for(i=0; i<numRowsOut; i++) {
+            for(j=0; j<numColsOut; j++) {
+                outImage->data.F64[i][j] = inImage->data.F64[j][i];
+            }
+        }
+    }
+
+    return outImage;
+}
+
+psImage* psMatrixEigenvectors(psImage* outImage, psImage* inImage)
+{
+    psS32 numRows = 0;
+    psS32 numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix *out = NULL;
+    gsl_matrix *in = NULL;
+
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_IMAGE_CHECK_NULL(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_IMAGE_CHECK_EMPTY(inImage, outImage);
+    psImageRecycle(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    in = gsl_matrix_alloc(numRows, numCols);
+    psImageToGslMatrix(in, inImage);
+    out = gsl_matrix_alloc(numRows, numCols);
+
+    // 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);
+
+    // Copy GSL matrix data to psImage data
+    gslMatrixToPsImage(outImage, out);
+
+    // Free GSL structs
+    gsl_matrix_free(in);
+    gsl_matrix_free(out);
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector* psMatrixToVector(psVector* outVector, const psImage* inImage)
+{
+    psS32 size = 0;
+
+    #define psMatrixToVector_EXIT {psFree(outVector); return NULL;}
+
+    // Error checks
+    PS_IMAGE_CHECK_NULL_GENERAL(inImage, psMatrixToVector_EXIT);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_IMAGE_CHECK_EMPTY_GENERAL(inImage, psMatrixToVector_EXIT);
+
+    if (inImage->numRows == 1) {
+        // Create transposed row vector
+        psVectorRecycle(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if (inImage->numCols == 1) {
+        // Create non-transposed column vector
+        psVectorRecycle(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "Image does not have dim with 1 col or 1 row: (%d x %d).",
+                inImage->numRows, inImage->numCols);
+        return outVector;
+    }
+
+    PS_VECTOR_CHECK_NULL(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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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)
+{
+    psS32 size = 0;
+
+    // Error checks
+    PS_VECTOR_CHECK_NULL(inVector, outImage);
+
+    if (inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_VECTOR_CHECK_EMPTY(inVector, outImage);
+        psImageRecycle(outImage, 1, inVector->n, PS_TYPE_F64);
+        // More checks for PS_DIMEN_VECTOR
+        if (outImage->numCols > 1) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image has more than 1 column: numCols = %d.",
+                    outImage->numCols);
+            return outImage;
+        } else if (outImage->numRows != inVector->n) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "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_VECTOR_CHECK_EMPTY(inVector, outImage);
+        psImageRecycle(outImage, inVector->n, 1, PS_TYPE_F64);
+        // More checks for PS_DIMEN_TRANSV
+        if (outImage->numRows > 1) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image has more than 1 row: numRows = %d.",
+                    outImage->numRows);
+            return outImage;
+        } else if (outImage->numCols != inVector->n) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "Image and vector sizes differ: (%d vs %d).",
+                    outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numCols;
+    }
+
+    PS_IMAGE_CHECK_NULL(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/rel4/psLib/src/math/psMatrix.h
===================================================================
--- /branches/rel4/psLib/src/math/psMatrix.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psMatrix.h	(revision 3057)
@@ -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.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 22:17:29 $
+ *
+ *  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
+    psF32 *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.
+ */
+psF32 *psMatrixDeterminant(
+    const psImage* 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/rel4/psLib/src/math/psMinimize.c
===================================================================
--- /branches/rel4/psLib/src/math/psMinimize.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psMinimize.c	(revision 3057)
@@ -0,0 +1,1853 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.101 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: must follow coding name standards on local functions.
+ *
+ */
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMinimize.h"
+#include "psStats.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+#define PS_SEG psLib
+#define PS_PWD dataManip
+#define PS_FILE psMinimize
+/*****************************************************************************/
+/* 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: Use a static vector.
+ *****************************************************************************/
+void psBuildSums1D(psF64 x,
+                   psS32 polyOrder,
+                   psVector* sums)
+{
+    psS32 i = 0;
+    psF64 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?
+ *****************************************************************************/
+psF32 *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");
+
+    psS32 i;
+    psS32 k;
+    psF32 sig;
+    psF32 p;
+    psS32 n = y->n;
+    psF32 *u = (psF32 *) psAlloc(n * sizeof(psF32));
+    psF32 *derivs2 = (psF32 *) psAlloc(n * sizeof(psF32));
+    psF32 *X = (psF32 *) & (x->data.F32[0]);
+    psF32 *Y = (psF32 *) & (y->data.F32[0]);
+    psF32 qn;
+
+    // XXX: The second derivatives at the endpoints, undefined in the SDR,
+    // are set in psConstants.h: PS_LEFT_SPLINE_DERIV, PS_RIGHT_SPLINE_DERIV.
+    derivs2[0] = -0.5;
+    u[0]= (3.0/(X[1]-X[0])) * ((Y[1]-Y[0])/(X[1]-X[0]) - PS_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])) * (PS_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]);
+    }
+
+    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: This is F32 only
+ *****************************************************************************/
+/*
+psF32 p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         psF32 X)
+{
+    PS_PTR_CHECK_NULL(spline, NAN);
+    PS_INT_CHECK_NON_NEGATIVE(spline->n, NAN);
+    PS_PTR_CHECK_NULL(spline->domains, NAN);
+    PS_PTR_CHECK_NULL(spline->p_psDeriv2, NAN);
+    PS_VECTOR_CHECK_NULL(x, NAN);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(y, NAN);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NAN);
+ 
+    psS32 n;
+    psS32 klo;
+    psS32 khi;
+    psF32 H;
+    psF32 A;
+    psF32 B;
+    psF32 C;
+    psF32 D;
+    psF32 Y;
+ 
+    n = spline->n;
+    klo = p_psVectorBinDisect32(spline->domains, (spline->n)+1, X);
+    if (klo < 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: psMinimize.c: p_psNRSpline1DEval(): p_psVectorBinDisect32 returned an error (%d).\n", klo);
+        return(NAN);
+    }
+    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
+{
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(y, NULL);
+
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() begin ----\n");
+    psS32 numSplines = (y->n)-1;
+    psF32 tmp;
+    psF32 H;
+    psS32 i;
+    psF32 slope;
+    psVector *x32 = NULL;
+    psVector *y32 = NULL;
+    psVector *yErr32 = NULL;
+    static psVector *x32Static = NULL;
+    static psVector *y32Static = NULL;
+    static psVector *yErr32Static = NULL;
+
+    PS_VECTOR_CONVERT_F64_TO_F32_STATIC(y, y32, y32Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        PS_VECTOR_GEN_YERR_STATIC_F32(yErr32Static, y->n);
+        yErr32 = yErr32Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(yErr, NULL);
+        PS_VECTOR_CONVERT_F64_TO_F32_STATIC(yErr, yErr32, yErr32Static);
+    }
+
+    // If x==NULL, create an x32 vector with x values set to (0:n).
+    if (x == NULL) {
+        PS_VECTOR_GEN_X_INDEX_STATIC_F32(x32Static, y->n);
+        x32 = x32Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+        PS_VECTOR_CONVERT_F64_TO_F32_STATIC(x, x32, x32Static);
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(x32, y32, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(yErr32, y32, NULL);
+
+    /*
+        XXX:
+        This can not be implemented until SDR states what order spline should be
+        created.
+        Should we error if mySpline is not NULL?
+        Should we error if mySPline is not NULL?
+    */
+    if (mySpline == NULL) {
+        mySpline = psSpline1DAllocGeneric(x32, 3);
+    }
+    PS_PTR_CHECK_NULL(mySpline, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(mySpline->n, NULL);
+
+    if (y32->n != (1 + mySpline->n)) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "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(PS_ERR_BAD_PARAMETER_SIZE, true,
+                "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",
+                x32->data.F32[i],
+                x32->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);
+}
+
+
+/******************************************************************************
+XXX: We assume unnormalized gaussians.
+ *****************************************************************************/
+psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss1D() begin ----\n");
+    psF32 x;
+    psS32 i;
+    psF32 mean = params->data.F32[0];
+    psF32 stdev = params->data.F32[1];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "(mean, stdev) is (%f, %f)\n", mean, stdev);
+
+    if (deriv == NULL) {
+        deriv = psImageAlloc(params->n, coords->n, PS_TYPE_F32);
+    } else {
+        PS_IMAGE_CHECK_SIZE(deriv, params->n, coords->n, NULL);
+        PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    }
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        out->data.F32[i] = psGaussian(x, mean, stdev, false);
+    }
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        psF32 tmp = (x - mean) * psGaussian(x, mean, stdev, false);
+        deriv->data.F32[i][0] = tmp / (stdev * stdev);
+        tmp = (x - mean) * (x - mean) *
+              psGaussian(x, mean, stdev, 0);
+        deriv->data.F32[i][1] = tmp / (stdev * stdev * stdev);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss1D() end ----\n");
+    return(out);
+}
+
+/*
+XXX: from bug 230:
+ 
+We first perform a rotation:
+u = - (x-x0)*cos(theta) + (y-y0)*sin(theta)
+v = (x-x0)*cos(theta) + (y-y0)*sin(theta)
+ 
+Here u is the major axis, and v is the minor axis, x0,y0 is the centre, and
+theta is the position angle.
+ 
+Then the flux is
+ 
+flux = norm * exp(-( u*u/2.0/sigmau/sigmau + v*v/2.0/sigmav/sigmav)
+)/2.0/pi/sigmau/sigmav
+ 
+Here sigmau and sigmav are the widths of the major and minor axes.
+ 
+The "norm" parameter in the equation above corresponds to the normalisation.
+ 
+Suggest order:
+ 
+norm
+x0
+y0
+sigma_u
+sigma_v
+theta
+*/
+
+psVector *psMinimizeLMChi2Gauss2D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psF64 normalization = params->data.F32[0];
+    psF64 x0 = params->data.F32[1];
+    psF64 y0 = params->data.F32[2];
+    psF64 sigmaX = params->data.F32[3];
+    psF64 sigmaY = params->data.F32[4];
+    psF64 theta = params->data.F32[5];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    if (deriv == NULL) {
+        deriv = psImageAlloc(params->n, coords->n, PS_TYPE_F32);
+    } else {
+        PS_IMAGE_CHECK_SIZE(deriv, 6, coords->n, NULL);
+        PS_IMAGE_CHECK_TYPE(deriv, PS_TYPE_F32, NULL);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss2D() begin ----\n");
+
+    for (psS32 i=0;i<coords->n;i++) {
+        psF64 x = ((psVector *) coords->data[i])->data.F32[0];
+        psF64 y = ((psVector *) coords->data[i])->data.F32[0];
+
+        psF64 u = - (x-x0)*cos(theta) + (y-y0)*sin(theta);
+        psF64 v = (x-x0)*cos(theta) + (y-y0)*sin(theta);
+
+        psF64 flux = normalization * exp(-( u*u/(2.0 * sigmaX * sigmaX) +
+                                            v*v/(2.0 * sigmaY * sigmaY)))/
+                     (2.0 * M_PI * sigmaX * sigmaY);
+        out->data.F32[i] = flux;
+
+        // XXX: Calculate these correctly.
+        deriv->data.F32[i][0] = 0.0;
+        deriv->data.F32[i][1] = 0.0;
+        deriv->data.F32[i][2] = 0.0;
+        deriv->data.F32[i][3] = 0.0;
+        deriv->data.F32[i][4] = 0.0;
+        deriv->data.F32[i][5] = 0.0;
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2Gauss2D() end ----\n");
+    return(out);
+}
+
+/******************************************************************************
+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.
+ 
+XXX: Must update the covar matrix.
+ *****************************************************************************/
+psBool psMinimizeLMChi2(psMinimization *min,
+                        psImage *covar,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *x,
+                        const psVector *y,
+                        const psVector *yErr,
+                        psMinimizeLMChi2Func func)
+{
+    PS_PTR_CHECK_NULL(min, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_EMPTY(y, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(x, y, NULL);
+    PS_PTR_CHECK_NULL(func, NULL);
+
+    if (paramMask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(params, paramMask, NULL);
+    }
+    if (yErr != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(y, yErr, NULL);
+    }
+    if (covar != NULL) {
+        PS_IMAGE_CHECK_SIZE(covar, params->n, params->n, NULL);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2() begin ----\n");
+    psS32 numData = y->n;
+    psS32 numParams = params->n;
+    psS32 i;
+    psS32 j;
+    psS32 k;
+    psS32 l;
+    psS32 n;
+    psS32 p;
+    psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *perm = NULL;
+
+    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);
+    psImage *deriv = psImageAlloc(numParams, numData, PS_TYPE_F32);
+    psVector *currValueVec = NULL;
+    psVector *newValueVec = NULL;
+    psF32 currChi2 = 0.0;
+    psF32 newChi2 = 0.0;
+    psF32 lamda = 0.00005;
+    lamda = 0.05;
+
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimize", 6,
+            "min->tol is %f\n", min->tol);
+
+    for (p=0;p<numParams;p++) {
+        origParams->data.F32[p] = params->data.F32[p];
+    }
+
+    min->lastDelta = PS_MAX_F32;
+    min->iter = 0;
+
+    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "------------------------------------------------------\n");
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
+
+        //
+        // Calculate the current values and chi-squared of the function.
+        //
+        currChi2 = 0.0;
+        currValueVec = func(deriv, params, x);
+        for (n=0;n<numData;n++) {
+            currChi2+= (currValueVec->data.F32[n] - y->data.F32[n]) *
+                       (currValueVec->data.F32[n] - y->data.F32[n]);
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "data[%d], chi2 calculation+= (%f - %f)^2\n", n,
+                    currValueVec->data.F32[n], y->data.F32[n]);
+        }
+
+        for (p=0;p<numParams;p++) {
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
+        }
+        psTrace(".psLib.dataManip.psMinimize", 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->data.F32[n][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])+=
+                    (y->data.F32[n] - currValueVec->data.F32[n]) *
+                    deriv->data.F32[n][p];
+            }
+            // XXX: multiply by -1 here?
+            (beta->data.F64[p])*= -1.0;
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
+        }
+        psFree(currValueVec);
+
+        //
+        // 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->data.F32[n][k] *
+                                            deriv->data.F32[n][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] =
+                        (psF64) ((1.0 + lamda) * alpha->data.F32[j][k]);
+                } else {
+                    A->data.F64[j][k] = (psF64) alpha->data.F32[j][k];
+                }
+            }
+        }
+        for (j=0;j<numParams;j++) {
+            psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n");
+            for (k=0;k<numParams;k++) {
+                psTrace(".psLib.dataManip.psMinimize", 6, "%f ", A->data.F64[j][k]);
+            }
+            psTrace(".psLib.dataManip.psMinimize", 6, "Matrix A[][]:\n");
+        }
+
+        //
+        // Solve A * alpha = Beta
+        //
+        // XXX: How do we know if these functions were successful?
+        //
+        aOut = psMatrixLUD(aOut, &perm, A);
+        paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
+
+        //
+        // Mask any masked parameters.
+        //
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimize", 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] -
+                                         (psF32) paramDeltasF64->data.F64[i];
+            }
+        }
+
+        psTrace(".psLib.dataManip.psMinimize", 6,
+                "Calling func() with new parameters:\n");
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimize", 6,
+                    "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
+        }
+
+
+        //
+        // Calculate new function values.
+        //
+        newChi2 = 0.0;
+        newValueVec = func(deriv, newParams, x);
+        for (n=0;n<numData;n++) {
+            newChi2+= (newValueVec->data.F32[n] - y->data.F32[n]) *
+                      (newValueVec->data.F32[n] - y->data.F32[n]);
+
+        }
+        psFree(newValueVec);
+
+        psTrace(".psLib.dataManip.psMinimize", 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] = (psF32) newParams->data.F32[i];
+            }
+            lamda*= 0.1;
+            psTrace(".psLib.dataManip.psMinimize", 4, "*** Reducing lamda by factor of 10\n");
+        } else {
+            lamda*= 10.0;
+            psTrace(".psLib.dataManip.psMinimize", 4, "*** Increasing lamda by factor of 10\n");
+        }
+        psTrace(".psLib.dataManip.psMinimize", 4,
+                "lamda is %f\n", lamda);
+        min->iter++;
+    }
+    psFree(beta);
+    psFree(perm);
+    psFree(paramDeltasF64);
+    psFree(origParams);
+    psFree(newParams);
+    psFree(alpha);
+    psFree(A);
+    psFree(aOut);
+    psFree(deriv);
+
+    if ((min->iter < min->maxIter) ||
+            (min->lastDelta <= min->tol)) {
+        return(true);
+    }
+
+    psTrace(".psLib.dataManip.psMinimize", 4,
+            "---- psMinimizeLMChi2() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+VectorFitPolynomial1DCheb():  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 *VectorFitPolynomial1DCheby(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    psS32 j;
+    psS32 k;
+    psS32 n = x->n;
+    psF64 fac;
+    psF64 sum;
+    PS_VECTOR_GEN_STATIC_RECYCLED(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.
+    psF64 min = -1.0;
+    psF64 max = 1.0;
+    psF64 bma = 0.5 * (max-min);  // 1
+    psF64 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 (psS32 i=0;i<n;i++) {
+        // NR 5.8.4
+        psF64 Y = cos(M_PI * (0.5 + ((psF32) i)) / ((psF32) n));
+        psF64 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.VectorFitPolynomial1DCheby", 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/((psF32) 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 * ((psF32) j) * (0.5 + ((psF32) k)) / ((psF32) n));
+        }
+
+        myPoly->coeff[j] = fac * sum;
+    }
+
+    return(myPoly);
+}
+
+/******************************************************************************
+VectorFitPolynomial1DOrd():  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* VectorFitPolynomial1DOrd(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    psS32 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;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 k = 0;
+    psVector* xSums = NULL;
+
+    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
+            "---- VectorFitPolynomial1DOrd() begin ----\n");
+    // printf("VectorFitPolynomial1D()\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);
+    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;
+        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++) {
+            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++) {
+            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];
+                }
+            }
+        }
+    }
+
+    // XXX: How do we know if these routines were successful?
+    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]);
+    }
+
+    psFree(A);
+    psFree(ALUD);
+    psFree(B);
+    psFree(coeffs);
+    psFree(X);
+    psFree(outPerm);
+    psFree(xSums);
+
+    psTrace(".psLib.dataManip.VectorFitPolynomial1DOrd", 4,
+            "---- VectorFitPolynomial1DOrd() 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)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(myPoly->n, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_EMPTY(y, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(y, NULL);
+
+    psS32 i;
+    psVector *x64 = NULL;
+    psVector *y64 = NULL;
+    psVector *yErr64 = NULL;
+    static psVector *x64Static = NULL;
+    static psVector *y64Static = NULL;
+    static psVector *yErr64Static = NULL;
+
+    PS_VECTOR_CONVERT_F32_TO_F64_STATIC(y, y64, y64Static);
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        PS_VECTOR_GEN_YERR_STATIC_F64(yErr64Static, y->n);
+        yErr64 = yErr64Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(yErr, NULL);
+        PS_VECTOR_CONVERT_F32_TO_F64_STATIC(yErr, yErr64, yErr64Static);
+    }
+
+    // If x==NULL, create an x64 vector with x values set to (0:n).
+    if (x == NULL) {
+        PS_VECTOR_GEN_X_INDEX_STATIC_F64(x64Static, y->n);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVectorRangeF64(x64Static, -1.0, 1.0);
+        }
+        x64 = x64Static;
+    } else {
+        PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+        PS_VECTOR_CONVERT_F32_TO_F64_STATIC(x, x64, x64Static);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVectorRangeF64(x64, -1.0, 1.0);
+        }
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(x64, y64, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(yErr64, y64, NULL);
+
+    // Call the appropriate vector fitting routine.
+    psPolynomial1D *rc = NULL;
+    if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        rc = VectorFitPolynomial1DCheby(myPoly, x64, y64, yErr64);
+    } else if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        rc = VectorFitPolynomial1DOrd(myPoly, x64, y64, yErr64);
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "unknown polynomial type.\n");
+        return(NULL);
+    }
+    if (rc == NULL) {
+        psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    return(myPoly);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+psMinimization *psMinimizationAlloc(psS32 maxIter,
+                                    psF32 tol)
+{
+    PS_INT_CHECK_NON_NEGATIVE(maxIter, NULL);
+
+    psMinimization *min = psAlloc(sizeof(psMinimization));
+    min->maxIter = maxIter;
+    min->tol = tol;
+    min->value = 0.0;
+    min->iter = 0;
+    min->lastDelta = 0.0;
+
+    return(min);
+}
+
+// This macro takes as input the vector BASE and adds a multiple of the vector
+// LINE to it.  We assume BASEMASK is non-null.
+#define PS_VECTOR_ADD_MULTIPLE(BASE, BASEMASK, LINE, OUT, MUL) \
+for (psS32 i=0;i<BASE->n;i++) { \
+    if (BASEMASK->data.U8[i] == 0) { \
+        OUT->data.F32[i] = BASE->data.F32[i] + (MUL * LINE->data.F32[i]); \
+    } else { \
+        OUT->data.F32[i] = BASE->data.F32[i]; \
+    } \
+} \
+
+#define PS_VECTOR_F32_CHECK_ZERO_VECTOR(IN, BOOL_VAR) \
+BOOL_VAR = true; \
+for (psS32 i=0;i<IN->n;i++) { \
+    if (fabs(IN->data.F32[i]) >= FLT_EPSILON) { \
+        BOOL_VAR = false; \
+        break; \
+    } \
+} \
+
+#define PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(IN, INMASK, BOOL_VAR) \
+BOOL_VAR = true; \
+for (psS32 i=0;i<IN->n;i++) { \
+    if ((INMASK->data.U8[i] == 0) && (fabs(IN->data.F32[i]) >= FLT_EPSILON)) { \
+        BOOL_VAR = false; \
+        break; \
+    } \
+} \
+
+
+/******************************************************************************
+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) < f(param + a * line)
+f(param + b * line) < f(param + c * line)
+a < b < c
+ 
+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.
+ 
+XXX:
+output bracket vector should be an input as well.
+*****************************************************************************/
+psVector *p_psDetermineBracket(psVector *params,
+                               psVector *line,
+                               const psVector *paramMask,
+                               const psArray *coords,
+                               psMinimizePowellFunc func)
+{
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psS32 iter = 100;
+    psF32 aDir = 0.0;
+    psF32 cDir = 0.0;
+    psF32 new_aDir = 0.0;
+    psF32 new_cDir = 0.0;
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    psF32 stepSize = PS_DETERMINE_BRACKET_STEP_SIZE;
+    psVector *tmp = NULL;
+    psBool boolLineIsNull = true;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    // If the line vector is zero, then return NULL.
+    PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(params, paramMask, boolLineIsNull);
+    if (boolLineIsNull == true) {
+        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;
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, a);
+    fa = func(tmp, coords);
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, b);
+    fb = func(tmp, coords);
+
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+    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;
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, a);
+        fa = func(tmp, coords);
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+        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);
+}
+
+
+#define RETURN_FINAL_BRACKET(d) \
+if (a < c) { \
+    bracket->data.F32[0] = a; \
+    bracket->data.F32[1] = b; \
+    bracket->data.F32[2] = c; \
+} else { \
+    bracket->data.F32[0] = c; \
+    bracket->data.F32[1] = b; \
+    bracket->data.F32[2] = a; \
+} \
+psTrace(".psLib.dataManip.p_psDetermineBracket", 4, \
+        "---- p_psDetermineBracket() end ----\n"); \
+psTrace(".psLib.dataManip.p_psDetermineBracket", 4, "Final bracket (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", a, b, c, fa, fb, fc); \
+return(bracket); \
+
+#define PS_DETERMINE_BRACKET_MAX_ITERATIONS 100
+psVector *p_psDetermineBracket2(psVector *params,
+                                psVector *line,
+                                const psVector *paramMask,
+                                const psArray *coords,
+                                psMinimizePowellFunc func)
+{
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psS32 iter = 0;
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmp, params->n, PS_TYPE_F32);
+    psBool boolLineIsNull = true;
+    psF32 prevMin = 0.0;
+    psS32 countMin = 0;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    // If the line vector is zero, then return NULL.
+    PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(params, paramMask, boolLineIsNull);
+    if (boolLineIsNull == true) {
+        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");
+        return(NULL);
+    }
+
+    // We determine in what x-direction does the function decrease.
+    a = 0.0;
+    fa = func(params, coords);
+    b = 0.5;
+    iter = 0;
+    do {
+        b*= (1.0 + PS_DETERMINE_BRACKET_STEP_SIZE);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, b);
+        fb = func(tmp, coords);
+    } while ((fabs(fb - fa) < FLT_EPSILON) && (iter++ < 100));
+
+    if (fb > fa) {
+        a = b;
+        fa = fb;
+        b = 0.0;
+        fb = func(params, coords);
+    }
+    c = b;
+
+    // At this point we have (a, b) and we know that (fa >= fb).  Initially, c=b;
+    // We keep stretching b out further from "a" until (fc > previous fc).  If
+    // that happens, then we have our bracket.
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    iter = 0;
+    while (iter < PS_DETERMINE_BRACKET_MAX_ITERATIONS) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "psDetermineBracket(): iterationA %d\n", iter);
+        c+= (1.0 + PS_DETERMINE_BRACKET_STEP_SIZE) * (c - a);
+
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmp, c);
+        fc = func(tmp, coords);
+
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "Iteration(%d) (bracket): (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", iter, a, b, c, fa, fb, fc);
+
+        if ((fb < fa) && (fb < fc)) {
+            RETURN_FINAL_BRACKET();
+        } else {
+            b = c;
+            fb = fc;
+        }
+
+        // This code maintains a count of how many times the minimum fc has
+        // stayed the same.  If it gets too high, we exit this loop.
+        if (fc == prevMin) {
+            countMin++;
+        } else {
+            countMin = 0;
+        }
+        prevMin = fc;
+        if (countMin == 10) {
+            RETURN_FINAL_BRACKET();
+        }
+
+        iter++;
+    }
+
+    psFree(bracket);
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() end (NULL) (BAD) ----\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
+XXX: Since this is an internal function, many of the parameter checks are
+     redundant.
+ *****************************************************************************/
+#define PS_LINEMIN_MAX_ITERATIONS 30
+psF32 p_psLineMin(psMinimization *min,
+                  psVector *params,
+                  psVector *line,
+                  const psVector *paramMask,
+                  const psArray *coords,
+                  psMinimizePowellFunc func)
+{
+    PS_PTR_CHECK_NULL(min, NAN);
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_EMPTY(params, NAN);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(line, NAN);
+    PS_VECTOR_CHECK_EMPTY(line, NAN);
+    PS_VECTOR_CHECK_TYPE(line, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_NULL(paramMask, NAN);
+    PS_VECTOR_CHECK_EMPTY(paramMask, NAN);
+    PS_VECTOR_CHECK_TYPE(paramMask, PS_TYPE_U8, NAN);
+    PS_PTR_CHECK_NULL(coords, NAN);
+    PS_PTR_CHECK_NULL(func, NAN);
+    psVector *bracket;
+    psF32 a = 0.0;
+    psF32 b = 0.0;
+    psF32 c = 0.0;
+    psF32 n = 0.0;
+    psF32 fa = 0.0;
+    psF32 fb = 0.0;
+    psF32 fc = 0.0;
+    psF32 fn = 0.0;
+    psF32 mul = 0.0;
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpa, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpb, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpc, params->n, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(tmpn, params->n, PS_TYPE_F32);
+    psS32 i = 0;
+    psS32 boolLineIsNull = true;
+    psS32 numIterations = 0;
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4, "---- p_psLineMin() begin ----\n");
+    PS_VECTOR_F32_CHECK_ZERO_VECTOR(line, boolLineIsNull);
+
+    if (boolLineIsNull == true) {
+        min->value = func(params, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 2,
+                "p_psLineMin() called with zero line vector.  Return 0.0.  Function value is %f\n", min->value);
+        return(0.0);
+    }
+
+    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_psDetermineBracket2(params, line, paramMask, coords, func);
+    if (bracket == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not bracket minimum.  Returning NAN.\n");
+        return(NAN);
+    }
+    numIterations = 0;
+    while (numIterations < PS_LINEMIN_MAX_ITERATIONS) {
+        numIterations++;
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "p_psLineMin(): iteration %d\n", numIterations);
+
+        a = bracket->data.F32[0];
+        b = bracket->data.F32[1];
+        c = bracket->data.F32[2];
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpa, a);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpb, b);
+        PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, tmpc, c);
+        fa = func(tmpa, coords);
+        fb = func(tmpb, coords);
+        fc = func(tmpc, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "LineMin: f(%f %f %f) is (%f %f %f)\n", 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,
+                "LineMin: new bracket is (%f %f %f)\n", 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)) {
+            PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, params, mul);
+            min->value = func(params, coords);
+            psFree(bracket);
+            psTrace(".psLib.dataManip.p_psLineMin", 4,
+                    "---- p_psLineMin() end.a (%f) (%f) ----\n", mul, min->value);
+            return(mul);
+        }
+    }
+
+    mul = bracket->data.F32[1];
+    PS_VECTOR_ADD_MULTIPLE(params, paramMask, line, params, mul);
+    min->value = func(params, coords);
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() end.b (%f) %f ----\n", mul, min->value);
+
+    psFree(bracket);
+    return(mul);
+}
+
+
+/******************************************************************************
+This routine must minimize a possibly multi-dimensional function.  The
+function to be minimized "func" is:
+    psF32 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: Check for F32 types?
+ *****************************************************************************/
+#define PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS 20
+#define PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE 0.01
+
+psBool psMinimizePowell(psMinimization *min,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *coords,
+                        psMinimizePowellFunc func)
+{
+    PS_PTR_CHECK_NULL(min, NULL);
+    PS_VECTOR_CHECK_NULL(params, NULL);
+    PS_VECTOR_CHECK_EMPTY(params, NULL);
+    PS_VECTOR_CHECK_TYPE(params, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(func, NULL);
+    psS32 numDims = params->n;
+    PS_VECTOR_GEN_STATIC_RECYCLED(pQP, numDims, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(u, numDims, PS_TYPE_F32);
+    PS_VECTOR_GEN_STATIC_RECYCLED(Q, numDims, PS_TYPE_F32);
+    psS32 i = 0;
+    psS32 j = 0;
+    psVector *myParamMask = NULL;
+    psMinimization dummyMin;
+    psF32 mul = 0.0;
+    psF32 baseFuncVal = 0.0;
+    psF32 currFuncVal = 0.0;
+    psS32 biggestIter = 0;
+    psF32 biggestDiff = 0.0;
+    psS32 iterationNumber = 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);
+
+    if (paramMask == NULL) {
+        myParamMask = psVectorRecycle(myParamMask, params->n, PS_TYPE_U8);
+        p_psMemSetPersistent(myParamMask, true);
+        p_psMemSetPersistent(myParamMask->data.V, true);
+        for (i=0;i<myParamMask->n;i++) {
+            myParamMask->data.U8[i] = 0;
+        }
+    } else {
+        myParamMask = (psVector *) paramMask;
+    }
+    PS_VECTOR_CHECK_SIZE_EQUAL(params, myParamMask, NULL);
+
+    // 1: Set v[i] to be the unit vectors for each dimension in params
+    psArray *v = psArrayAlloc(numDims);
+    for (i=0;i<numDims;i++) {
+        (v->data[i]) = (psVector *) psVectorAlloc(numDims, PS_TYPE_F32);
+        for (j=0;j<numDims;j++) {
+            if (i == j) {
+                ((psVector *) (v->data[i]))->data.F32[j] = 1.0;
+            } else {
+                ((psVector *) (v->data[i]))->data.F32[j] = 0.0;
+            }
+        }
+    }
+
+    // 2: Set Q to be the initial params (P in the ADD)
+    for (i=0;i<numDims;i++) {
+        Q->data.F32[i] = params->data.F32[i];
+    }
+
+    while (iterationNumber < min->maxIter) {
+        iterationNumber++;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "psMinimizePowell() iteration %d\n", iterationNumber);
+
+        // 3: For each dimension in params, move Q only in the vector v[i] to
+        //    minimize the function.
+
+        baseFuncVal = func(Q, coords);
+        currFuncVal = baseFuncVal;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "Current function value is %f\n", currFuncVal);
+
+        biggestDiff = 0;
+        biggestIter = 0;
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                dummyMin.maxIter = PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS;
+                dummyMin.tol = PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE;
+                mul = p_psLineMin(&dummyMin,
+                                  Q,
+                                  ((psVector *) v->data[i]),
+                                  myParamMask,
+                                  coords,
+                                  func);
+                if (isnan(mul)) {
+                    psError(PS_ERR_UNKNOWN, false,
+                            "Could not perform line minimization.  Returning FALSE.\n");
+                    psFree(v);
+                    return(false);
+                }
+                psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                        "LineMin along dimension %d has multiple %f\n", i, mul);
+
+                if (fabs(dummyMin.value - currFuncVal) > biggestDiff) {
+                    biggestDiff = fabs(dummyMin.value - currFuncVal);
+                    biggestIter = i;
+                }
+                currFuncVal = dummyMin.value;
+            }
+        }
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "New function value is %f\n", currFuncVal);
+
+        // 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[i]=Q[i]-P[i] (%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.
+        for (i=0;i<numDims;i++) {
+            psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                    "u[i] is %f\n", u->data.F32[i]);
+        }
+
+        mul = p_psLineMin(&dummyMin, params, u, myParamMask, coords, func);
+        if (isnan(mul)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not perform line minimization.  Returning FALSE.\n");
+            psFree(v);
+            return(false);
+        }
+
+        // 6:
+        if (dummyMin.value > currFuncVal) {
+            psFree(v);
+            min->iter = iterationNumber;
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (1)(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];
+            }
+        }
+        psF32 fqp = func(pQP, coords);
+        psF32 term1 = (baseFuncVal - currFuncVal) - biggestDiff;
+        term1*= term1;
+        term1*= 2.0 * (baseFuncVal - (2.0 * currFuncVal) + fqp);
+        psF32 term2 = baseFuncVal - fqp;
+        term2*= term2 * biggestDiff;
+        if (term1 < term2) {
+            for (i=0;i<numDims;i++) {
+                if (myParamMask->data.U8[i] == 0) {
+                    ((psVector *) v->data[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) {
+            psFree(v);
+            min->iter = iterationNumber;
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (2) (true) ----\n");
+            return(true);
+        }
+    }
+
+    psFree(v);
+    min->iter = iterationNumber;
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() end (0) (false) ----\n");
+    return(false);
+}
+
+
+/******************************************************************************
+XXX: We assume unnormalized gaussians.
+XXX: Currently, yErr is ignored.
+ *****************************************************************************/
+psVector *psMinimizePowellChi2Gauss1D(const psVector *params,
+                                      const psArray *coords)
+{
+    PS_PTR_CHECK_NULL(coords, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+
+    psF32 x;
+    psS32 i;
+    psF32 mean = params->data.F32[0];
+    psF32 stdev = params->data.F32[1];
+    psVector *out = psVectorAlloc(coords->n, PS_TYPE_F32);
+
+    for (i=0;i<coords->n;i++) {
+        x = ((psVector *) (coords->data[i]))->data.F32[0];
+        out->data.F32[i] = psGaussian(x, mean, stdev, false);
+    }
+
+    return(out);
+}
+
+/******************************************************************************
+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
+ *****************************************************************************/
+psF32 myPowellChi2Func(const psVector *params,
+                       const psArray *coords)
+{
+    psTrace(".psLib.dataManip.myPowellChi2Func", 4,
+            "---- myPowellChi2Func() begin ----\n");
+    PS_VECTOR_CHECK_NULL(params, NAN);
+    PS_VECTOR_CHECK_EMPTY(params, NAN);
+    PS_VECTOR_CHECK_NULL(myValue, NAN);
+    PS_VECTOR_CHECK_EMPTY(myValue, NAN);
+    PS_PTR_CHECK_NULL(coords, NAN);
+
+    psF32 chi2 = 0.0;
+    psF32 d;
+    psS32 i;
+    psVector *tmp;
+
+    tmp = Chi2PowellFunc(params, coords);
+    if (myError == NULL) {
+        for (i=0;i<coords->n;i++) {
+            d = (tmp->data.F32[i] - myValue->data.F32[i]);
+            chi2+= d * d;
+        }
+    } else {
+        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);
+    psTrace(".psLib.dataManip.myPowellChi2Func", 4,
+            "---- myPowellChi2Func() end (chi2 is %f) ----\n", chi2);
+    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().
+ *****************************************************************************/
+psBool 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/rel4/psLib/src/math/psMinimize.h
===================================================================
--- /branches/rel4/psLib/src/math/psMinimize.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psMinimize.h	(revision 3057)
@@ -0,0 +1,126 @@
+/** @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.37 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-22 05:09:32 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PS_MINIMIZE_H)
+#define PS_MINIMIZE_H
+
+/** \file psMinimize.h
+ *  \brief minimization operations
+ *  \ingroup Stats
+ */
+/** \addtogroup Stats
+ *  \{
+ */
+
+#include "psVector.h"
+#include "psMemory.h"
+#include "psArray.h"
+#include "psImage.h"
+#include "psMatrix.h"
+#include "psFunctions.h"
+#include "psStats.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psConstants.h"
+
+typedef struct
+{
+    psS32 maxIter;                       ///< Convergence limit
+    psF32 tol;                         ///< Error Tolerance
+    psF32 value;                       ///< Value of function at minimum
+    psS32 iter;                          ///< Number of iterations required
+    psF32 lastDelta;                   ///< The last difference for the fit
+}
+psMinimization;
+
+psMinimization *psMinimizationAlloc(psS32 maxIter,
+                                    psF32 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
+                               );
+
+typedef
+psVector* (*psMinimizeLMChi2Func)(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *x);
+
+psBool psMinimizeLMChi2(psMinimization *min,
+                        psImage *covar,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *x,
+                        const psVector *y,
+                        const psVector *yErr,
+                        psMinimizeLMChi2Func func);
+
+typedef
+psF32 (*psMinimizePowellFunc)(const psVector *params,
+                              const psArray *coords);
+
+psBool psMinimizePowell(psMinimization *min,
+                        psVector *params,
+                        const psVector *paramMask,
+                        const psArray *coords,
+                        psMinimizePowellFunc func);
+
+psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,
+                                  const psVector *params,
+                                  const psArray *coords);
+
+psVector *psMinimizePowellChi2Gauss1D(const psVector *params,
+                                      const psArray *coords);
+
+typedef
+psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,
+                                      const psArray *coords);
+
+psBool 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/rel4/psLib/src/math/psPolynomial.c
===================================================================
--- /branches/rel4/psLib/src/math/psPolynomial.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psPolynomial.c	(revision 3057)
@@ -0,0 +1,2216 @@
+/** @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.83 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: What happens if the polyEVal functions are called with data of the wrong
+ *       type?
+ *  XXX: Should the "coeffErr[]" be used as well?  Bug ???.  Ignore coeffErr
+ *
+ */
+/*****************************************************************************/
+/*  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 "psLogMsg.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+#include "psDataManipErrors.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* 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);
+static void spline1DFree(psSpline1D *tmpSpline);
+static psS32 vectorBinDisectF32(psF32 *bins,psS32 numBins,psF32 x);
+static psS32 vectorBinDisectS32(psS32 *bins,psS32 numBins,psS32 x);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+static void spline1DFree(psSpline1D *tmpSpline)
+{
+    psS32 i;
+
+    if (tmpSpline == NULL) {
+        return;
+    }
+
+    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);
+
+    return;
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+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(psS32 maxChebyPoly)
+{
+    PS_INT_CHECK_NON_NEGATIVE(maxChebyPoly, NULL);
+
+    psPolynomial1D **chebPolys = NULL;
+    psS32 i = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF32 ordPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "---- Calling ordPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 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?
+// XXX: We assume that x is scaled between -1.0 and 1.0;
+static psF32 chebPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF32 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);
+
+    /*
+
+    psS32 n;
+    psS32 i;
+    psF32 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]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+static psF32 ordPolynomial2DEval(psF32 x,
+                                 psF32 y,
+                                 const psPolynomial2D* myPoly)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial2DEval(psF32 x, psF32 y, const psPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 wSum = 1.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF64 dOrdPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 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?
+static psF64 dChebPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF64 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);
+}
+
+static psF64 dOrdPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 wSum = 1.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+
+/*****************************************************************************
+fullInterpolate1DF32(): 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?
+ *****************************************************************************/
+#define FUNC_MACRO_FULL_INTERPOLATE_1D(TYPE) \
+static psF32 fullInterpolate1D##TYPE(ps##TYPE *domain, \
+                                     ps##TYPE *range, \
+                                     psS32 n, \
+                                     ps##TYPE x) \
+{ \
+    \
+    psS32 i; \
+    psS32 m; \
+    static psVector *p = NULL; \
+    p = psVectorRecycle(p, n, PS_TYPE_##TYPE); \
+    p_psMemSetPersistent(p, true); \
+    p_psMemSetPersistent(p->data.TYPE, true); \
+    \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n); \
+    \
+    for (i=0;i<n;i++) { \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "domain/range is (%f %f)\n", domain[i], range[i]); \
+    } \
+    \
+    for (i=0;i<n;i++) { \
+        p->data.TYPE[i] = range[i]; \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[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.TYPE[i] = (((x-domain[i+m]) * p->data.TYPE[i]) + \
+                               ((domain[i]-x) * p->data.TYPE[i+1])) / \
+                              (domain[i] - domain[i+m]); \
+            /*printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.TYPE[i], domain[i], x, p->data.TYPE[i+1], domain[i], domain[i+m]); \
+             */ \
+            psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                    "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[i]); \
+        } \
+    } \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() end ----\n"); \
+    \
+    return(p->data.TYPE[0]); \
+} \
+
+/*
+FUNC_MACRO_FULL_INTERPOLATE_1D(U8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(F64)
+*/
+FUNC_MACRO_FULL_INTERPOLATE_1D(F32)
+
+
+/*****************************************************************************
+interpolate1DF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+static psF32 interpolate1DF32(psF32 *domain,
+                              psF32 *range,
+                              psS32 n,
+                              psS32 order,
+                              psF32 x)
+{
+    PS_PTR_CHECK_NULL(domain, NAN)
+    PS_PTR_CHECK_NULL(range, NAN)
+    // XXX: Check valid values for n, order, and x?
+
+    psS32 binNum;
+    psS32 numIntPoints = order+1;
+    psS32 origin;
+
+    psTrace(".psLib.dataManip.psFunctions.interpolate1DF32", 4,
+            "---- interpolate1DF32() begin ----\n");
+
+    binNum = vectorBinDisectF32(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.interpolate1DF32", 4,
+            "---- interpolate1DF32() end ----\n");
+    return(fullInterpolate1DF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************/
+/*  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]
+ *****************************************************************************/
+psF32 psGaussian(psF32 x, psF32 mean, psF32 sigma, psBool normal)
+{
+    psF32 tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        tmp = 1.0 / PS_SQRT_F32(2.0 * M_PI * (sigma * sigma));
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    p_psGaussianDev()
+ This private routine (formerly a psLib API 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.
+ 
+XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* p_psGaussianDev(psF32 mean, psF32 sigma, psS32 Npts)
+{
+    PS_INT_CHECK_NON_NEGATIVE(Npts, NULL);
+
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    psS32 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);
+    }
+
+    // XXX: Should I free r, T as well?  This is a memory leak.
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(psS32 n,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->coeffErr = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->coeffErr = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->coeffErr[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->coeffErr = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->coeffErr[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->coeffErr[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->coeffErr = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->coeffErr[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->coeffErr[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->coeffErr[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+psF32 psPolynomial1DEval(const psPolynomial1D* myPoly, psF32 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial1DEvalVector(const psPolynomial1D *myPoly,
+                                   const psVector *x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(myPoly, x->data.F32[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial2DEval(const psPolynomial2D* myPoly, psF32 x, psF32 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial2DEvalVector(const psPolynomial2D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial3DEval(const psPolynomial3D* myPoly, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial3DEvalVector(const psPolynomial3D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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);
+}
+
+psF32 psPolynomial4DEval(const psPolynomial4D* myPoly, psF32 w, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial4DEvalVector(const psPolynomial4D *myPoly,
+                                   const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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(psS32 n,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->coeffErr = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->coeffErr = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->coeffErr[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->coeffErr = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->coeffErr[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->coeffErr[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->coeffErr = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->coeffErr[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->coeffErr[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->coeffErr[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+
+psF64 psDPolynomial1DEval(const psDPolynomial1D* myPoly, psF64 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial1DEvalVector(const psDPolynomial1D *myPoly,
+                                    const psVector *x)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(myPoly,
+                                               x->data.F64[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial2DEval(const psDPolynomial2D* myPoly,
+                          psF64 x,
+                          psF64 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial2DEvalVector(const psDPolynomial2D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial3DEval(const psDPolynomial3D* myPoly,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial3DEvalVector(const psDPolynomial3D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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);
+}
+
+psF64 psDPolynomial4DEval(const psDPolynomial4D* myPoly,
+                          psF64 w,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial4DEvalVector(const psDPolynomial4D *myPoly,
+                                    const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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 {
+//    psS32 n;
+//    psPolynomial1D **spline;
+//    psF32 *p_psDeriv2;
+//    psF32 *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(psS32 numSplines,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max)
+{
+    PS_INT_CHECK_NON_NEGATIVE(numSplines, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_FLOAT_CHECK_NON_EQUAL(max, min, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psF32 tmpDomain;
+    psF32 width;
+
+    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 = (psF32 *) psAlloc((numSplines+1) * sizeof(psF32));
+    width = (max - min) / ((psF32) 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;
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order)
+{
+    PS_VECTOR_CHECK_NULL(bounds, NULL);
+    PS_VECTOR_CHECK_EMPTY(bounds, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psS32 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);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (psF32 *) psAlloc((bounds->n) * sizeof(psF32));
+
+    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])) {
+                psError(PS_ERR_UNKNOWN, true, "data points must be distinct\n");
+            }
+        }
+    }
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+/*****************************************************************************
+vectorBinDisectF32(): This is a macro for a private function which takes as
+input a vector an array of data as well as a single value for that data.  The
+input vector values are assumed to be non-decreasing (v[i-1] <= v[i] for all
+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).
+ *****************************************************************************/
+#define FUNC_MACRO_VECTOR_BIN_DISECT(TYPE) \
+static psS32 vectorBinDisect##TYPE(ps##TYPE *bins, \
+                                   psS32 numBins, \
+                                   ps##TYPE x) \
+{ \
+    psS32 min; \
+    psS32 max; \
+    psS32 mid; \
+    \
+    psTrace(".psLib.dataManip.psFunctions.vectorBinDisect##TYPE", 4, \
+            "---- Calling vectorBinDisect##TYPE(%f)\n", x); \
+    \
+    if (x < bins[0]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, x, bins[0], bins[numBins-1]); \
+        return(-2); \
+    } \
+    \
+    if (x > bins[numBins-1]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, 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.vectorBinDisect##TYPE", 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.vectorBinDisect##TYPE", 4, \
+                    "---- Exiting vectorBinDisect##TYPE(): 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.vectorBinDisect##TYPE", 4, \
+            "---- Exiting vectorBinDisect##TYPE(): bin %d\n", min); \
+    return(min); \
+} \
+
+FUNC_MACRO_VECTOR_BIN_DISECT(S8)
+FUNC_MACRO_VECTOR_BIN_DISECT(S16)
+FUNC_MACRO_VECTOR_BIN_DISECT(S32)
+FUNC_MACRO_VECTOR_BIN_DISECT(S64)
+FUNC_MACRO_VECTOR_BIN_DISECT(U8)
+FUNC_MACRO_VECTOR_BIN_DISECT(U16)
+FUNC_MACRO_VECTOR_BIN_DISECT(U32)
+FUNC_MACRO_VECTOR_BIN_DISECT(U64)
+FUNC_MACRO_VECTOR_BIN_DISECT(F32)
+FUNC_MACRO_VECTOR_BIN_DISECT(F64)
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(bins, -4);
+    PS_VECTOR_CHECK_EMPTY(bins, -4);
+    PS_PTR_CHECK_NULL(x, -6);
+    PS_PTR_CHECK_TYPE_EQUAL(x, bins, -3);
+    psS8* strType;
+
+    switch (x->type.type) {
+    case PS_TYPE_U8:
+        return(vectorBinDisectU8(bins->data.U8, bins->n, x->data.U8));
+    case PS_TYPE_U16:
+        return(vectorBinDisectU16(bins->data.U16, bins->n, x->data.U16));
+    case PS_TYPE_U32:
+        return(vectorBinDisectU32(bins->data.U32, bins->n, x->data.U32));
+    case PS_TYPE_U64:
+        return(vectorBinDisectU64(bins->data.U64, bins->n, x->data.U64));
+    case PS_TYPE_S8:
+        return(vectorBinDisectS8(bins->data.S8, bins->n, x->data.S8));
+    case PS_TYPE_S16:
+        return(vectorBinDisectS16(bins->data.S16, bins->n, x->data.S16));
+    case PS_TYPE_S32:
+        return(vectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    case PS_TYPE_S64:
+        return(vectorBinDisectS64(bins->data.S64, bins->n, x->data.S64));
+    case PS_TYPE_F32:
+        return(vectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    case PS_TYPE_F64:
+        return(vectorBinDisectF64(bins->data.F64, bins->n, x->data.F64));
+    case PS_TYPE_C32:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_C64:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_PTR:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_BOOL:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+    return(-3);
+}
+
+/*****************************************************************************
+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: 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,
+                                psS32 order,
+                                psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(domain, NULL);
+    PS_VECTOR_CHECK_NULL(range, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, x, NULL);
+
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if (order > (domain->n - 1)) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS,
+                order);
+        return(NULL);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(interpolate1DF32(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((psF64)
+                                            interpolate1DF32(domain32->data.F32,
+                                                             range32->data.F32,
+                                                             domain32->n,
+                                                             order,
+                                                             (psF32) 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 {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "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
+(vectorBinDisectF32()).  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.
+ *****************************************************************************/
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NAN);
+    PS_INT_CHECK_NON_NEGATIVE(spline->n, NAN);
+
+    psS32 binNum;
+    psS32 n;
+
+    n = spline->n;
+    binNum = vectorBinDisectF32(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(spline->spline[0],
+                                      x));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(spline->spline[n-1],
+                                      x));
+        }
+    }
+
+    return(psPolynomial1DEval(spline->spline[binNum],
+                              x));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+
+    psS32 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,
+                                         (psF32) x->data.F64[i]
+                                     );
+        }
+    } else {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel4/psLib/src/math/psPolynomial.h
===================================================================
--- /branches/rel4/psLib/src/math/psPolynomial.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psPolynomial.h	(revision 3057)
@@ -0,0 +1,437 @@
+/** @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 GLG, MHPCC
+*
+*  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-29 22:15:51 $
+*
+*  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 psF32      value on the gaussian curve given the input parameters
+ */
+psF32 psGaussian(
+    psF32 x,                           ///< Value at which to evaluate
+    psF32 mean,                        ///< Mean for the Gaussian
+    psF32 stddev,                      ///< Standard deviation for the Gaussian
+    psBool 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* p_psGaussianDev(
+    psF32 mean,                        ///< The mean of the Gaussian
+    psF32 sigma,                       ///< The sigma of the Gaussian
+    psS32 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
+    psS32 n;                             ///< Number of terms
+    psF32 *coeff;                      ///< Coefficients
+    psF32 *coeffErr;                   ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF32 **coeff;                     ///< Coefficients
+    psF32 **coeffErr;                  ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ***coeff;                    ///< Coefficients
+    psF32 ***coeffErr;                 ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ****coeff;                   ///< Coefficients
+    psF32 ****coeffErr;                ///< Error in coefficients
+    psU8 ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    psS32 n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial1DEval(
+    const psPolynomial1D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x                           ///< location at which to evaluate
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial2DEval(
+    const psPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y                           ///< y location at which to evaluate
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial3DEval(
+    const psPolynomial3D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial4DEval(
+    const psPolynomial4D* myPoly,       ///< Coefficients for the polynomial
+    psF32 w,                           ///< w location at which to evaluate
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+psVector *psPolynomial1DEvalVector(
+    const psPolynomial1D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psPolynomial2DEvalVector(
+    const psPolynomial2D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psPolynomial3DEvalVector(
+    const psPolynomial3D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psPolynomial4DEvalVector(
+    const psPolynomial4D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 n;                             ///< Number of terms
+    psF64 *coeff;                     ///< Coefficients
+    psF64 *coeffErr;                  ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF64 **coeff;                    ///< Coefficients
+    psF64 **coeffErr;                 ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ***coeff;                   ///< Coefficients
+    psF64 ***coeffErr;                ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ****coeff;                  ///< Coefficients
+    psF64 ****coeffErr;               ///< Error in coefficients
+    psU8 ****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(
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial1DEval(
+    const psDPolynomial1D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x                          ///< Value at which to evaluate
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial2DEval(
+    const psDPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF64 x,                           ///< Value x at which to evaluate
+    psF64 y            ///< Value y at which to evaluate
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial3DEval(
+    const psDPolynomial3D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial4DEval(
+    const psDPolynomial4D* myPoly,      ///< Coefficients for the polynomial
+    psF64 w,                          ///< Value w at which to evaluate
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+psVector *psDPolynomial1DEvalVector(
+    const psDPolynomial1D *myPoly, ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psDPolynomial2DEvalVector(
+    const psDPolynomial2D *myPoly,  ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psDPolynomial3DEvalVector(
+    const psDPolynomial3D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psDPolynomial4DEvalVector(
+    const psDPolynomial4D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+
+
+typedef struct
+{
+    psS32 n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    psF32 *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    psF32 *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(psS32 n,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order);
+
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+);
+
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+);
+
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                psS32 order,
+                                psScalar *x);
+
+psF32 p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         psF32 X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel4/psLib/src/math/psRandom.c
===================================================================
--- /branches/rel4/psLib/src/math/psRandom.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psRandom.c	(revision 3057)
@@ -0,0 +1,140 @@
+/** @file psRandom.c
+*  \brief Random Number Generators
+*  \ingroup Math
+*
+*  This file will hold the functions which allocate, free,
+*  and evaluate random number Generators.
+*
+*  @ingroup Math
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-15 01:15:09 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+#include <time.h>
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include "psMemory.h"
+#include "psRandom.h"
+#include "psScalar.h"
+#include "psError.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+#include "psConstants.h"
+#include "psDataManipErrors.h"
+
+psU64 p_psRandomGetSystemSeed()
+{
+    FILE*  fd;
+    psU64  seedVal = 0;
+    time_t timeVal;
+
+    fd = fopen("/dev/urandom","r");
+    if(fd == NULL) {
+        // Read system clock to get seed
+        seedVal = (psU64)time(&timeVal);
+    } else {
+        // Read urandom to get seed
+        fread(&seedVal, sizeof(psU64),1,fd);
+        // Close file
+        fclose(fd);
+    }
+
+    // Send log message of the system seed value used
+    psLogMsg(__func__,PS_LOG_INFO,"System random seed value used  seed = %llX hex",seedVal);
+
+    return seedVal;
+}
+
+psRandom *psRandomAlloc(psRandomType type,
+                        psU64 seed)
+{
+    gsl_rng   *r      = NULL;
+    psRandom  *myRNG  = NULL;
+
+    switch (type) {
+    case PS_RANDOM_TAUS:
+        myRNG = (psRandom*)psAlloc(sizeof(psRandom));
+        r = gsl_rng_alloc(gsl_rng_taus);
+        myRNG->gsl = r;
+        if(seed == 0) {
+            gsl_rng_set(myRNG->gsl,p_psRandomGetSystemSeed());
+        }
+        break;
+
+    default:
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE);
+        break;
+    }
+    return(myRNG);
+}
+
+void psRandomReset(psRandom *rand,
+                   psU64 seed)
+{
+    // Check null psRandom
+    if(rand==NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+    } else {
+        // Check seed value to see if system seed should be used
+        if(seed == 0) {
+            gsl_rng_set(rand->gsl,p_psRandomGetSystemSeed());
+        } else {
+            gsl_rng_set(rand->gsl, seed);
+        }
+    }
+}
+
+psF64 psRandomUniform(const psRandom *r)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        return(gsl_rng_uniform(r->gsl));
+    }
+}
+
+psF64 psRandomGaussian(const psRandom *r)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        // XXX: What should sigma be?
+        return(gsl_ran_gaussian(r->gsl, 1.0));
+    }
+}
+
+psF64 psRandomPoisson(const psRandom *r, psF64 mean)
+{
+    // Check null psRandom variable
+    if(r == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                true,
+                PS_ERRORTEXT_psRandom_NULL_RANDOM_VAR);
+        return(0);
+    } else {
+        return((psF64) gsl_ran_poisson(r->gsl, mean));
+    }
+}
+
Index: /branches/rel4/psLib/src/math/psRandom.h
===================================================================
--- /branches/rel4/psLib/src/math/psRandom.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psRandom.h	(revision 3057)
@@ -0,0 +1,59 @@
+/** @file psRandom.h
+*  \brief Random Number Generators
+*  \ingroup Math
+*
+*  This file will hold the prototypes for procedures which allocate, free,
+*  and evaluate random number Generators.
+*
+*  @ingroup Math
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-21 23:25:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#if !defined(PS_RANDOM_H)
+#define PS_RANDOM_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psVector.h"
+#include "psScalar.h"
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+/** \addtogroup Math
+ *  \{
+ */
+
+typedef enum {
+    PS_RANDOM_TAUS    ///< A maximally equidistributed combined Tausworthe generator.
+} psRandomType;
+
+typedef struct
+{
+    psRandomType type; ///< The type of RNG
+    gsl_rng *gsl; ///< The RNG itself
+}
+psRandom;
+
+psRandom *psRandomAlloc(psRandomType type,
+                        psU64 seed);
+
+void psRandomReset(psRandom *rand,
+                   psU64 seed);
+
+psF64 psRandomUniform(const psRandom *r);
+psF64 psRandomGaussian(const psRandom *r);
+psF64 psRandomPoisson(const psRandom *r, psF64 mean);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel4/psLib/src/math/psSpline.c
===================================================================
--- /branches/rel4/psLib/src/math/psSpline.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psSpline.c	(revision 3057)
@@ -0,0 +1,2216 @@
+/** @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.83 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 23:25:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: What happens if the polyEVal functions are called with data of the wrong
+ *       type?
+ *  XXX: Should the "coeffErr[]" be used as well?  Bug ???.  Ignore coeffErr
+ *
+ */
+/*****************************************************************************/
+/*  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 "psLogMsg.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+#include "psDataManipErrors.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* 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);
+static void spline1DFree(psSpline1D *tmpSpline);
+static psS32 vectorBinDisectF32(psF32 *bins,psS32 numBins,psF32 x);
+static psS32 vectorBinDisectS32(psS32 *bins,psS32 numBins,psS32 x);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+static void spline1DFree(psSpline1D *tmpSpline)
+{
+    psS32 i;
+
+    if (tmpSpline == NULL) {
+        return;
+    }
+
+    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);
+
+    return;
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    psS32 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)
+{
+    psS32 x = 0;
+    psS32 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)
+{
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+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(psS32 maxChebyPoly)
+{
+    PS_INT_CHECK_NON_NEGATIVE(maxChebyPoly, NULL);
+
+    psPolynomial1D **chebPolys = NULL;
+    psS32 i = 0;
+    psS32 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);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF32 ordPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "---- Calling ordPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.ordPolynomial1DEval", 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?
+// XXX: We assume that x is scaled between -1.0 and 1.0;
+static psF32 chebPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF32 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);
+
+    /*
+
+    psS32 n;
+    psS32 i;
+    psF32 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]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+static psF32 ordPolynomial2DEval(psF32 x,
+                                 psF32 y,
+                                 const psPolynomial2D* myPoly)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial2DEval(psF32 x, psF32 y, const psPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF32 ordPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF32 polySum = 0.0;
+    psF32 wSum = 1.0;
+    psF32 xSum = 1.0;
+    psF32 ySum = 1.0;
+    psF32 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);
+}
+
+static psF32 chebPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF32 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+static psF64 dOrdPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    psS32 loop_x = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 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?
+static psF64 dChebPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    psVector *d;
+    psS32 n;
+    psS32 i;
+    psF64 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);
+}
+
+static psF64 dOrdPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                           psPolynomial1DEval(chebPolys[loop_y], y);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_x], x) *
+                               psPolynomial1DEval(chebPolys[loop_y], y) *
+                               psPolynomial1DEval(chebPolys[loop_z], z);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+static psF64 dOrdPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psF64 polySum = 0.0;
+    psF64 wSum = 1.0;
+    psF64 xSum = 1.0;
+    psF64 ySum = 1.0;
+    psF64 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);
+}
+
+static psF64 dChebPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)
+{
+    PS_FLOAT_CHECK_RANGE(w, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(x, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(y, -1.0, 1.0, 0.0);
+    PS_FLOAT_CHECK_RANGE(z, -1.0, 1.0, 0.0);
+    psS32 loop_w = 0;
+    psS32 loop_x = 0;
+    psS32 loop_y = 0;
+    psS32 loop_z = 0;
+    psS32 i = 0;
+    psF64 polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    psS32 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(chebPolys[loop_w], w) *
+                                   psPolynomial1DEval(chebPolys[loop_x], x) *
+                                   psPolynomial1DEval(chebPolys[loop_y], y) *
+                                   psPolynomial1DEval(chebPolys[loop_z], z);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+
+/*****************************************************************************
+fullInterpolate1DF32(): 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?
+ *****************************************************************************/
+#define FUNC_MACRO_FULL_INTERPOLATE_1D(TYPE) \
+static psF32 fullInterpolate1D##TYPE(ps##TYPE *domain, \
+                                     ps##TYPE *range, \
+                                     psS32 n, \
+                                     ps##TYPE x) \
+{ \
+    \
+    psS32 i; \
+    psS32 m; \
+    static psVector *p = NULL; \
+    p = psVectorRecycle(p, n, PS_TYPE_##TYPE); \
+    p_psMemSetPersistent(p, true); \
+    p_psMemSetPersistent(p->data.TYPE, true); \
+    \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n); \
+    \
+    for (i=0;i<n;i++) { \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "domain/range is (%f %f)\n", domain[i], range[i]); \
+    } \
+    \
+    for (i=0;i<n;i++) { \
+        p->data.TYPE[i] = range[i]; \
+        psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[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.TYPE[i] = (((x-domain[i+m]) * p->data.TYPE[i]) + \
+                               ((domain[i]-x) * p->data.TYPE[i+1])) / \
+                              (domain[i] - domain[i+m]); \
+            /*printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.TYPE[i], domain[i], x, p->data.TYPE[i+1], domain[i], domain[i+m]); \
+             */ \
+            psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 6, \
+                    "p->data.TYPE[%d] is %f\n", i, p->data.TYPE[i]); \
+        } \
+    } \
+    psTrace(".psLib.dataManip.psFunctions.fullInterpolate1D##TYPE", 4, \
+            "---- fullInterpolate1D##TYPE() end ----\n"); \
+    \
+    return(p->data.TYPE[0]); \
+} \
+
+/*
+FUNC_MACRO_FULL_INTERPOLATE_1D(U8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(U64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S8)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S16)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S32)
+FUNC_MACRO_FULL_INTERPOLATE_1D(S64)
+FUNC_MACRO_FULL_INTERPOLATE_1D(F64)
+*/
+FUNC_MACRO_FULL_INTERPOLATE_1D(F32)
+
+
+/*****************************************************************************
+interpolate1DF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+static psF32 interpolate1DF32(psF32 *domain,
+                              psF32 *range,
+                              psS32 n,
+                              psS32 order,
+                              psF32 x)
+{
+    PS_PTR_CHECK_NULL(domain, NAN)
+    PS_PTR_CHECK_NULL(range, NAN)
+    // XXX: Check valid values for n, order, and x?
+
+    psS32 binNum;
+    psS32 numIntPoints = order+1;
+    psS32 origin;
+
+    psTrace(".psLib.dataManip.psFunctions.interpolate1DF32", 4,
+            "---- interpolate1DF32() begin ----\n");
+
+    binNum = vectorBinDisectF32(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.interpolate1DF32", 4,
+            "---- interpolate1DF32() end ----\n");
+    return(fullInterpolate1DF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************/
+/*  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]
+ *****************************************************************************/
+psF32 psGaussian(psF32 x, psF32 mean, psF32 sigma, psBool normal)
+{
+    psF32 tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        tmp = 1.0 / PS_SQRT_F32(2.0 * M_PI * (sigma * sigma));
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    p_psGaussianDev()
+ This private routine (formerly a psLib API 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.
+ 
+XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* p_psGaussianDev(psF32 mean, psF32 sigma, psS32 Npts)
+{
+    PS_INT_CHECK_NON_NEGATIVE(Npts, NULL);
+
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    psS32 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);
+    }
+
+    // XXX: Should I free r, T as well?  This is a memory leak.
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(psS32 n,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->coeffErr = (psF32 *)psAlloc(n * sizeof(psF32));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->coeffErr = (psF32 **)psAlloc(nX * sizeof(psF32 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->coeffErr[x] = (psF32 *)psAlloc(nY * sizeof(psF32));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->coeffErr = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->coeffErr[x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->coeffErr[x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                    psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->coeffErr = (psF32 ****)psAlloc(nW * sizeof(psF32 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->coeffErr[w] = (psF32 ***)psAlloc(nX * sizeof(psF32 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->coeffErr[w][x] = (psF32 **)psAlloc(nY * sizeof(psF32 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->coeffErr[w][x][y] = (psF32 *)psAlloc(nZ * sizeof(psF32));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+psF32 psPolynomial1DEval(const psPolynomial1D* myPoly, psF32 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial1DEvalVector(const psPolynomial1D *myPoly,
+                                   const psVector *x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(myPoly, x->data.F32[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial2DEval(const psPolynomial2D* myPoly, psF32 x, psF32 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial2DEvalVector(const psPolynomial2D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+psF32 psPolynomial3DEval(const psPolynomial3D* myPoly, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial3DEvalVector(const psPolynomial3D *myPoly,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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);
+}
+
+psF32 psPolynomial4DEval(const psPolynomial4D* myPoly, psF32 w, psF32 x, psF32 y, psF32 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(ordPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(chebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psPolynomial4DEvalVector(const psPolynomial4D *myPoly,
+                                   const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F32, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                              myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i]);
+
+    }
+
+    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(psS32 n,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(n, NULL);
+
+    psS32 i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->coeffErr = (psF64 *)psAlloc(n * sizeof(psF64));
+    newPoly->mask = (psU8 *)psAlloc(n * sizeof(psU8));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(psS32 nX, psS32 nY,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+
+    psS32 x = 0;
+    psS32 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 = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->coeffErr = (psF64 **)psAlloc(nX * sizeof(psF64 *));
+    newPoly->mask = (psU8 **)psAlloc(nX * sizeof(psU8 *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->coeffErr[x] = (psF64 *)psAlloc(nY * sizeof(psF64));
+        newPoly->mask[x] = (psU8 *)psAlloc(nY * sizeof(psU8));
+    }
+    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(psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->coeffErr = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+    newPoly->mask = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->coeffErr[x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+        newPoly->mask[x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->coeffErr[x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+            newPoly->mask[x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+        }
+    }
+    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(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,
+                                      psPolynomialType type)
+{
+    PS_INT_CHECK_NON_NEGATIVE(nW, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nX, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nY, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(nZ, NULL);
+
+    psS32 w = 0;
+    psS32 x = 0;
+    psS32 y = 0;
+    psS32 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 = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->coeffErr = (psF64 ****)psAlloc(nW * sizeof(psF64 ***));
+    newPoly->mask = (psU8 ****)psAlloc(nW * sizeof(psU8 ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->coeffErr[w] = (psF64 ***)psAlloc(nX * sizeof(psF64 **));
+        newPoly->mask[w] = (psU8 ***)psAlloc(nX * sizeof(psU8 **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->coeffErr[w][x] = (psF64 **)psAlloc(nY * sizeof(psF64 *));
+            newPoly->mask[w][x] = (psU8 **)psAlloc(nY * sizeof(psU8 *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->coeffErr[w][x][y] = (psF64 *)psAlloc(nZ * sizeof(psF64));
+                newPoly->mask[w][x][y] = (psU8 *)psAlloc(nZ * sizeof(psU8));
+            }
+        }
+    }
+    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);
+}
+
+
+psF64 psDPolynomial1DEval(const psDPolynomial1D* myPoly, psF64 x)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial1DEval(x, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial1DEvalVector(const psDPolynomial1D *myPoly,
+                                    const psVector *x)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psS32 i;
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(myPoly,
+                                               x->data.F64[i]);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial2DEval(const psDPolynomial2D* myPoly,
+                          psF64 x,
+                          psF64 y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial2DEvalVector(const psDPolynomial2D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i]);
+
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+psF64 psDPolynomial3DEval(const psDPolynomial3D* myPoly,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial3DEvalVector(const psDPolynomial3D *myPoly,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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);
+}
+
+psF64 psDPolynomial4DEval(const psDPolynomial4D* myPoly,
+                          psF64 w,
+                          psF64 x,
+                          psF64 y,
+                          psF64 z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(dOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(dChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE,
+                myPoly->type);
+    }
+    return(NAN);
+}
+
+psVector *psDPolynomial4DEvalVector(const psDPolynomial4D *myPoly,
+                                    const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z)
+{
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_VECTOR_CHECK_NULL(w, NULL);
+    PS_VECTOR_CHECK_TYPE(w, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE(x, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(y, NULL);
+    PS_VECTOR_CHECK_TYPE(y, PS_TYPE_F64, NULL);
+    PS_VECTOR_CHECK_NULL(z, NULL);
+    PS_VECTOR_CHECK_TYPE(z, PS_TYPE_F64, NULL);
+
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    psS32 i;
+    psS32 vecLen=x->n;
+
+    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(myPoly,
+                                               myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i]);
+
+    }
+
+    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 {
+//    psS32 n;
+//    psPolynomial1D **spline;
+//    psF32 *p_psDeriv2;
+//    psF32 *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(psS32 numSplines,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max)
+{
+    PS_INT_CHECK_NON_NEGATIVE(numSplines, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_FLOAT_CHECK_NON_EQUAL(max, min, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psF32 tmpDomain;
+    psF32 width;
+
+    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 = (psF32 *) psAlloc((numSplines+1) * sizeof(psF32));
+    width = (max - min) / ((psF32) 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;
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order)
+{
+    PS_VECTOR_CHECK_NULL(bounds, NULL);
+    PS_VECTOR_CHECK_EMPTY(bounds, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+
+    psSpline1D *tmp = NULL;
+    psS32 i;
+    psS32 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);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (psF32 *) psAlloc((bounds->n) * sizeof(psF32));
+
+    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])) {
+                psError(PS_ERR_UNKNOWN, true, "data points must be distinct\n");
+            }
+        }
+    }
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)spline1DFree);
+    return(tmp);
+}
+
+/*****************************************************************************
+vectorBinDisectF32(): This is a macro for a private function which takes as
+input a vector an array of data as well as a single value for that data.  The
+input vector values are assumed to be non-decreasing (v[i-1] <= v[i] for all
+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).
+ *****************************************************************************/
+#define FUNC_MACRO_VECTOR_BIN_DISECT(TYPE) \
+static psS32 vectorBinDisect##TYPE(ps##TYPE *bins, \
+                                   psS32 numBins, \
+                                   ps##TYPE x) \
+{ \
+    psS32 min; \
+    psS32 max; \
+    psS32 mid; \
+    \
+    psTrace(".psLib.dataManip.psFunctions.vectorBinDisect##TYPE", 4, \
+            "---- Calling vectorBinDisect##TYPE(%f)\n", x); \
+    \
+    if (x < bins[0]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, x, bins[0], bins[numBins-1]); \
+        return(-2); \
+    } \
+    \
+    if (x > bins[numBins-1]) { \
+        psLogMsg(__func__, PS_LOG_WARN, \
+                 "vectorBinDisect%s(): ordinate %f is outside vector range (%f - %f).", \
+                 #TYPE, 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.vectorBinDisect##TYPE", 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.vectorBinDisect##TYPE", 4, \
+                    "---- Exiting vectorBinDisect##TYPE(): 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.vectorBinDisect##TYPE", 4, \
+            "---- Exiting vectorBinDisect##TYPE(): bin %d\n", min); \
+    return(min); \
+} \
+
+FUNC_MACRO_VECTOR_BIN_DISECT(S8)
+FUNC_MACRO_VECTOR_BIN_DISECT(S16)
+FUNC_MACRO_VECTOR_BIN_DISECT(S32)
+FUNC_MACRO_VECTOR_BIN_DISECT(S64)
+FUNC_MACRO_VECTOR_BIN_DISECT(U8)
+FUNC_MACRO_VECTOR_BIN_DISECT(U16)
+FUNC_MACRO_VECTOR_BIN_DISECT(U32)
+FUNC_MACRO_VECTOR_BIN_DISECT(U64)
+FUNC_MACRO_VECTOR_BIN_DISECT(F32)
+FUNC_MACRO_VECTOR_BIN_DISECT(F64)
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(bins, -4);
+    PS_VECTOR_CHECK_EMPTY(bins, -4);
+    PS_PTR_CHECK_NULL(x, -6);
+    PS_PTR_CHECK_TYPE_EQUAL(x, bins, -3);
+    psS8* strType;
+
+    switch (x->type.type) {
+    case PS_TYPE_U8:
+        return(vectorBinDisectU8(bins->data.U8, bins->n, x->data.U8));
+    case PS_TYPE_U16:
+        return(vectorBinDisectU16(bins->data.U16, bins->n, x->data.U16));
+    case PS_TYPE_U32:
+        return(vectorBinDisectU32(bins->data.U32, bins->n, x->data.U32));
+    case PS_TYPE_U64:
+        return(vectorBinDisectU64(bins->data.U64, bins->n, x->data.U64));
+    case PS_TYPE_S8:
+        return(vectorBinDisectS8(bins->data.S8, bins->n, x->data.S8));
+    case PS_TYPE_S16:
+        return(vectorBinDisectS16(bins->data.S16, bins->n, x->data.S16));
+    case PS_TYPE_S32:
+        return(vectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    case PS_TYPE_S64:
+        return(vectorBinDisectS64(bins->data.S64, bins->n, x->data.S64));
+    case PS_TYPE_F32:
+        return(vectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    case PS_TYPE_F64:
+        return(vectorBinDisectF64(bins->data.F64, bins->n, x->data.F64));
+    case PS_TYPE_C32:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_C64:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_PTR:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    case PS_TYPE_BOOL:
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+    return(-3);
+}
+
+/*****************************************************************************
+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: 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,
+                                psS32 order,
+                                psScalar *x)
+{
+    PS_VECTOR_CHECK_NULL(domain, NULL);
+    PS_VECTOR_CHECK_NULL(range, NULL);
+    PS_PTR_CHECK_NULL(x, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(order, NULL);
+    PS_VECTOR_CHECK_SIZE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, range, NULL);
+    PS_PTR_CHECK_TYPE_EQUAL(domain, x, NULL);
+
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if (order > (domain->n - 1)) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS,
+                order);
+        return(NULL);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(interpolate1DF32(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((psF64)
+                                            interpolate1DF32(domain32->data.F32,
+                                                             range32->data.F32,
+                                                             domain32->n,
+                                                             order,
+                                                             (psF32) 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 {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "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
+(vectorBinDisectF32()).  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.
+ *****************************************************************************/
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NAN);
+    PS_INT_CHECK_NON_NEGATIVE(spline->n, NAN);
+
+    psS32 binNum;
+    psS32 n;
+
+    n = spline->n;
+    binNum = vectorBinDisectF32(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(spline->spline[0],
+                                      x));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(spline->spline[n-1],
+                                      x));
+        }
+    }
+
+    return(psPolynomial1DEval(spline->spline[binNum],
+                              x));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+)
+{
+    PS_PTR_CHECK_NULL(spline, NULL);
+    PS_VECTOR_CHECK_NULL(x, NULL);
+    PS_VECTOR_CHECK_TYPE_F32_OR_F64(x, NULL);
+
+    psS32 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,
+                                         (psF32) x->data.F64[i]
+                                     );
+        }
+    } else {
+        psS8* strType;
+        PS_TYPE_NAME(strType,x->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE,
+                PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED,
+                strType);
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel4/psLib/src/math/psSpline.h
===================================================================
--- /branches/rel4/psLib/src/math/psSpline.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psSpline.h	(revision 3057)
@@ -0,0 +1,437 @@
+/** @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 GLG, MHPCC
+*
+*  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-29 22:15:51 $
+*
+*  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 psF32      value on the gaussian curve given the input parameters
+ */
+psF32 psGaussian(
+    psF32 x,                           ///< Value at which to evaluate
+    psF32 mean,                        ///< Mean for the Gaussian
+    psF32 stddev,                      ///< Standard deviation for the Gaussian
+    psBool 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* p_psGaussianDev(
+    psF32 mean,                        ///< The mean of the Gaussian
+    psF32 sigma,                       ///< The sigma of the Gaussian
+    psS32 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
+    psS32 n;                             ///< Number of terms
+    psF32 *coeff;                      ///< Coefficients
+    psF32 *coeffErr;                   ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF32 **coeff;                     ///< Coefficients
+    psF32 **coeffErr;                  ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ***coeff;                    ///< Coefficients
+    psF32 ***coeffErr;                 ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF32 ****coeff;                   ///< Coefficients
+    psF32 ****coeffErr;                ///< Error in coefficients
+    psU8 ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    psS32 n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial1DEval(
+    const psPolynomial1D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x                           ///< location at which to evaluate
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial2DEval(
+    const psPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y                           ///< y location at which to evaluate
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial3DEval(
+    const psPolynomial3D* myPoly,       ///< Coefficients for the polynomial
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF32 psPolynomial4DEval(
+    const psPolynomial4D* myPoly,       ///< Coefficients for the polynomial
+    psF32 w,                           ///< w location at which to evaluate
+    psF32 x,                           ///< x location at which to evaluate
+    psF32 y,                           ///< y location at which to evaluate
+    psF32 z                           ///< z location at which to evaluate
+);
+
+psVector *psPolynomial1DEvalVector(
+    const psPolynomial1D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psPolynomial2DEvalVector(
+    const psPolynomial2D *myPoly,   ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psPolynomial3DEvalVector(
+    const psPolynomial3D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psPolynomial4DEvalVector(
+    const psPolynomial4D *myPoly,   ///< Coefficients for the polynomial
+    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
+);
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 n;                             ///< Number of terms
+    psF64 *coeff;                     ///< Coefficients
+    psF64 *coeffErr;                  ///< Error in coefficients
+    psU8 *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psF64 **coeff;                    ///< Coefficients
+    psF64 **coeffErr;                 ///< Error in coefficients
+    psU8 **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ***coeff;                   ///< Coefficients
+    psF64 ***coeffErr;                ///< Error in coefficients
+    psU8 ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    psS32 nW;                            ///< Number of terms in w
+    psS32 nX;                            ///< Number of terms in x
+    psS32 nY;                            ///< Number of terms in y
+    psS32 nZ;                            ///< Number of terms in z
+    psF64 ****coeff;                  ///< Coefficients
+    psF64 ****coeffErr;               ///< Error in coefficients
+    psU8 ****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(
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 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(
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 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(
+    psS32 nW,                            ///< Number of terms in w
+    psS32 nX,                            ///< Number of terms in x
+    psS32 nY,                            ///< Number of terms in y
+    psS32 nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial1DEval(
+    const psDPolynomial1D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x                          ///< Value at which to evaluate
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial2DEval(
+    const psDPolynomial2D* myPoly,       ///< Coefficients for the polynomial
+    psF64 x,                           ///< Value x at which to evaluate
+    psF64 y            ///< Value y at which to evaluate
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial3DEval(
+    const psDPolynomial3D* myPoly,      ///< Coefficients for the polynomial
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return psF32    result of polynomial at given location
+ */
+psF64 psDPolynomial4DEval(
+    const psDPolynomial4D* myPoly,      ///< Coefficients for the polynomial
+    psF64 w,                          ///< Value w at which to evaluate
+    psF64 x,                          ///< Value x at which to evaluate
+    psF64 y,                          ///< Value y at which to evaluate
+    psF64 z     ///< Value z at which to evaluate
+);
+
+psVector *psDPolynomial1DEvalVector(
+    const psDPolynomial1D *myPoly, ///< Coefficients for the polynomial
+    const psVector *x             ///< x locations at which to evaluate
+);
+
+psVector *psDPolynomial2DEvalVector(
+    const psDPolynomial2D *myPoly,  ///< Coefficients for the polynomial
+    const psVector *x,             ///< x locations at which to evaluate
+    const psVector *y             ///< y locations at which to evaluate
+);
+
+psVector *psDPolynomial3DEvalVector(
+    const psDPolynomial3D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+psVector *psDPolynomial4DEvalVector(
+    const psDPolynomial4D *myPoly,  ///< Coefficients for the polynomial
+    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
+);
+
+
+
+typedef struct
+{
+    psS32 n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    psF32 *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    psF32 *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(psS32 n,
+                            psS32 order,
+                            psF32 min,
+                            psF32 max);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   psS32 order);
+
+psF32 psSpline1DEval(
+    const psSpline1D *spline,
+    psF32 x
+);
+
+psVector *psSpline1DEvalVector(
+    const psSpline1D *spline,
+    const psVector *x
+);
+
+psS32 p_psVectorBinDisect(psVector *bins,
+                          psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                psS32 order,
+                                psScalar *x);
+
+psF32 p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         psF32 X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel4/psLib/src/math/psStats.c
===================================================================
--- /branches/rel4/psLib/src/math/psStats.c	(revision 3057)
+++ /branches/rel4/psLib/src/math/psStats.c	(revision 3057)
@@ -0,0 +1,2280 @@
+/** @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.110 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-14 23:27:56 $
+ *
+ *  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 "psLogMsg.h"
+#include "psError.h"
+#include "psStats.h"
+#include "psMinimize.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+#include "psDataManipErrors.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+#define PS_GAUSS_WIDTH 5       // The width of the Gaussian or boxcar smoothing.
+#define PS_CLIPPED_NUM_ITER_LB 1
+#define PS_CLIPPED_NUM_ITER_UB 10
+#define PS_CLIPPED_SIGMA_LB 1.0
+#define PS_CLIPPED_SIGMA_UB 10.0
+#define PS_POLY_MEDIAN_MAX_ITERATIONS 10
+
+#define PS_BIN_MIDPOINT(HISTOGRAM, BIN_NUM) \
+(0.5 * (HISTOGRAM->bounds->data.F32[(BIN_NUM)] + HISTOGRAM->bounds->data.F32[(BIN_NUM)+1]))
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+psVector* p_psConvertToF32(psVector* in);
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+psBool p_psGetStatValue(const psStats* stats, psF64 *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;
+    }
+}
+
+/******************************************************************************
+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().  Should we perform the sanity
+checks in each routine anyway?
+ 
+XXX: For many of these private stats routines, what should be done if there
+are no acceptable elements in the input vector (if no elements lie within
+range, or there are no unmasked elements, or the input vector is NULL)?
+Currently we set the value to NAN.
+ 
+XXX: Optimization: many routines have an "empty" boolean variable which keeps
+track of whether or not the vector has any valid elements.  This code can
+possibly be optimized away.
+ *****************************************************************************/
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.  If there was a problem with the mean calculation,
+this routine sets stats->sampleMean to NAN.
+ *****************************************************************************/
+psS32 p_psVectorSampleMean(const psVector* restrict myVector,
+                           const psVector* restrict errors,
+                           const psVector* restrict maskVector,
+                           psU32 maskVal,
+                           psStats* stats)
+{
+
+    psS32 i = 0;                // Loop index variable
+    psF32 mean = 0.0;           // The mean
+    psS32 count = 0;            // # of points in this mean
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (errors == NULL) {
+        if (stats->options & PS_STAT_USE_RANGE) {
+            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]) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    if ((stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+            }
+        } else {
+            if (maskVector != NULL) {
+                for (i = 0; i < myVector->n; i++) {
+                    if (!(maskVal & maskVector->data.U8[i])) {
+                        mean += myVector->data.F32[i];
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= (psF32)count;
+                } else {
+                    mean = NAN;
+                }
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    mean += myVector->data.F32[i];
+                }
+                mean /= (psF32)myVector->n;
+            }
+        }
+    } else {
+        psF32 errorDivisor = 0.0;
+        if (stats->options & PS_STAT_USE_RANGE) {
+            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]) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    if ((stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+            }
+        } else {
+            if (maskVector != NULL) {
+                for (i = 0; i < myVector->n; i++) {
+                    if (!(maskVal & maskVector->data.U8[i])) {
+                        mean += myVector->data.F32[i]/errors->data.F32[i];
+                        errorDivisor+= (1.0 / errors->data.F32[i]);
+                        count++;
+                    }
+                }
+                if (count != 0) {
+                    mean /= errorDivisor;
+                } else {
+                    mean = NAN;
+                }
+            } else {
+                for (i = 0; i < myVector->n; i++) {
+                    mean += myVector->data.F32[i]/errors->data.F32[i];
+                    errorDivisor+= (1.0 / errors->data.F32[i]);
+                }
+                mean /= errorDivisor;
+            }
+        }
+    }
+
+    stats->sampleMean = mean;
+    if (isnan(mean)) {
+        return(-1);
+    } else {
+        return(0);
+    }
+
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.  If there was a problem with the max calculation,
+this routine sets stats->max to NAN.
+ *****************************************************************************/
+psS32 p_psVectorMax(const psVector* restrict myVector,
+                    const psVector* restrict maskVector,
+                    psU32 maskVal,
+                    psStats* stats)
+{
+    psS32 i = 0;                // Loop index variable
+    psF32 max = -PS_MAX_F32;    // The calculated maximum
+    psS32 empty = true;         // Does this vector have valid elements?
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        max = myVector->data.F32[i];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    max = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    } 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];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    }
+    if (empty == false) {
+        stats->max = max;
+    } else {
+        stats->max = NAN;
+        return(1);
+    }
+    return(0);
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.  If there was a problem with the min calculation,
+this routine sets stats->min to NAN.
+ *****************************************************************************/
+psS32 p_psVectorMin(const psVector* restrict myVector,
+                    const psVector* restrict maskVector,
+                    psU32 maskVal,
+                    psStats* stats)
+{
+    psS32 i = 0;                // Loop index variable
+    psF32 min = PS_MAX_F32;   // The calculated maximum
+    psS32 empty = true;         // Does this vector have valid elements?
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (stats->min <= myVector->data.F32[i]) &&
+                            (myVector->data.F32[i] <= stats->max)) {
+                        min = myVector->data.F32[i];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    min = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    } 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];
+                        empty = false;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                    empty = false;
+                }
+            }
+        }
+    }
+
+    if (empty == false) {
+        stats->min = min;
+    } else {
+        stats->min = NAN;
+        return(1);
+    }
+    return(0);
+}
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): This routine returns
+"true" if the inputPsVector has 1 or more valid elements (a valid element is an
+unmasked element within the specified min/max range).  Otherwise, return
+"false".
+ *****************************************************************************/
+bool p_psVectorCheckNonEmpty(const psVector* restrict myVector,
+                             const psVector* restrict maskVector,
+                             psU32 maskVal,
+                             psStats* stats)
+{
+    PS_VECTOR_CHECK_NULL(myVector, -1);
+    PS_PTR_CHECK_NULL(stats, -1);
+    psS32 i = 0;                // Loop index variable
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    return(true);
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    return(true);
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    return(true);
+                }
+            }
+        } else {
+            if (myVector->n > 0) {
+                return(true);
+            }
+        }
+    }
+    return(false);
+}
+
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector that fall within the min/max
+range, if specified.
+ *****************************************************************************/
+psS32 p_psVectorNValues(const psVector* restrict myVector,
+                        const psVector* restrict maskVector,
+                        psU32 maskVal,
+                        psStats* stats)
+{
+    PS_VECTOR_CHECK_NULL(myVector, -1);
+    PS_PTR_CHECK_NULL(stats, -1);
+    psS32 i = 0;                // Loop index variable
+    psS32 numData = 0;          // The number of data points
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    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.  Returns true on success (including if there were
+no valid input vector elements).
+ 
+XXX: Use static vectors for sort arrays.
+ *****************************************************************************/
+bool p_psVectorSampleMedian(const psVector* restrict myVector,
+                            const psVector* restrict maskVector,
+                            psU32 maskVal,
+                            psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    psS32 i = 0;                        // Loop index variable
+    psS32 count = 0;
+    psS32 nValues = 0;
+
+    // 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);
+
+    // XXX: Is a warning message appropriate?  What value should we set the
+    // sampleMedian to?  Should we generate an error?
+    if (nValues <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleMedian(): no valid elements in input vector.\n");
+        return(true);
+        stats->sampleMedian = NAN;
+    }
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        // 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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count] = myVector->data.F32[i];
+                    count++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count] = myVector->data.F32[i];
+                    count++;
+                }
+            }
+        }
+    } 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];
+                    count++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    sortedVector = psVectorSort(sortedVector, unsortedVector);
+    if (sortedVector == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
+        return(false);
+    }
+
+    // Calculate the median exactly.  Use the average if the number of samples
+    // is even.
+    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);
+
+    // Return "true" on success.
+    return(true);
+}
+
+/******************************************************************************
+p_psVectorSmoothHistGaussian(): This routine smoothes the data in the input
+robustHistogram with a Gaussian of width sigma.
+ 
+XXX: Only PS_TYPE_F32 is supported.
+ 
+XXX: Write a general routine which smoothes a psVector.  This routine should
+call that.  Is that possible?
+ *****************************************************************************/
+psVector* p_psVectorSmoothHistGaussian(psHistogram* robustHistogram,
+                                       psF32 sigma)
+{
+    PS_PTR_CHECK_NULL(robustHistogram, NULL);
+    PS_PTR_CHECK_NULL(robustHistogram->bounds, NULL);
+
+    psS32 i = 0;                  // Loop index variable
+    psS32 j = 0;                  // Loop index variable
+    psF32 iMid;
+    psF32 jMid;
+    psS32 numBins = robustHistogram->nums->n;
+    psS32 numBounds = robustHistogram->bounds->n;
+    psVector* smooth = psVectorAlloc(numBins, PS_TYPE_F32);
+    psS32 jMin = 0;
+    psS32 jMax = 0;
+    psF32 firstBound = robustHistogram->bounds->data.F32[0];
+    psF32 lastBound = robustHistogram->bounds->data.F32[numBounds-1];
+    psScalar x;
+
+    x.type.type = PS_TYPE_F32;
+    for (i = 0; i < numBins; i++) {
+        // Determine the midpoint of bin i.
+        iMid = (robustHistogram->bounds->data.F32[i] +
+                robustHistogram->bounds->data.F32[i+1]) / 2.0;
+
+
+        // We determine the bin numbers corresponding to a range of data
+        // values surrounding iMid.  The ranges is of size
+        // s*PS_GAUSS_WIDTH*sigma
+
+        // YYY: The p_psVectorBinDisect() routine does much of the work of
+        // the following conditionals, however, it also reports a warning
+        // message.  I don't want the warning message so I reproduce the
+        // conditionals here.  Maybe p_psVectorBinDisect() should not produce
+        // warnings?
+
+        x.data.F32 = iMid - (PS_GAUSS_WIDTH * sigma);
+        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
+            jMin = p_psVectorBinDisect(robustHistogram->bounds, &x);
+            if (jMin < 0) {
+                psError(PS_ERR_UNEXPECTED_NULL,
+                        false,
+                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
+                return(NULL);
+            }
+        } else if (x.data.F32 <= firstBound) {
+            jMin = 0;
+        } else if (x.data.F32 >= lastBound) {
+            jMin = robustHistogram->bounds->n - 1;
+        }
+
+        x.data.F32 = iMid + (PS_GAUSS_WIDTH * sigma);
+        if ((x.data.F32 >= firstBound) && (x.data.F32 <= lastBound)) {
+            jMax = p_psVectorBinDisect(robustHistogram->bounds, &x);
+            if (jMax < 0) {
+                psError(PS_ERR_UNEXPECTED_NULL,
+                        false,
+                        PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM);
+                return(NULL);
+            }
+        } else if (x.data.F32 <= firstBound) {
+            jMax = 0;
+        } else if (x.data.F32 >= lastBound) {
+            jMax = robustHistogram->bounds->n - 1;
+        }
+
+        smooth->data.F32[i] = 0.0;
+        for (j = jMin ; j <= jMax ; j++) {
+            jMid = (robustHistogram->bounds->data.F32[j] +
+                    robustHistogram->bounds->data.F32[j+1]) / 2.0;
+            smooth->data.F32[i] +=
+                robustHistogram->nums->data.F32[j] *
+                psGaussian(jMid, iMid, sigma, true);
+        }
+    }
+
+    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
+ *****************************************************************************/
+bool p_psVectorSampleQuartiles(const psVector* restrict myVector,
+                               const psVector* restrict maskVector,
+                               psU32 maskVal,
+                               psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    psS32 i = 0;                  // Loop index variable
+    psS32 count = 0;              // # of points in this mean.
+    psS32 nValues = 0;            // # data points
+
+    // 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);
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        // 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]) &&
+                        (stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) && (myVector->data.F32[i] <= stats->max)) {
+                    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.
+    sortedVector = psVectorSort(sortedVector, unsortedVector);
+    if (sortedVector == NULL) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM);
+        return(false);
+    }
+
+    // Calculate the quartile points exactly.
+    // XXX: We should probably do a bin-midpoint if the quartile is not an
+    // integer.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+    return(true);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+ *****************************************************************************/
+void p_psVectorSampleStdevOLD(const psVector* restrict myVector,
+                              const psVector* restrict errors,
+                              const psVector* restrict maskVector,
+                              psU32 maskVal,
+                              psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 countInt = 0;           // # of data points being used
+    psF32 countFloat = 0.0;     // # of data points being used
+    psF32 mean = 0.0;           // The mean
+    psF32 diff = 0.0;           // Used in calculating stdev
+    psF32 sumSquares = 0.0;     // temporary variable
+    psF32 sumDiffs = 0.0;       // temporary variable
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
+    }
+    // If the mean is NAN, then generate a warning and set the stdev to NAN.
+    if (0 != isnan(stats->sampleMean)) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
+        return;
+    }
+
+    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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    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;
+        }
+    }
+    if (countInt == 0) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d).  Setting stats->sampleStdev = NAN.\n", countInt);
+    } else if (countInt == 1) {
+        stats->sampleStdev = 0.0;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d).  Setting stats->sampleStdev = 0.0.\n", countInt);
+    } else {
+        countFloat = (psF32)countInt;
+        stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    }
+}
+/******************************************************************************
+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 errors,
+                           const psVector* restrict maskVector,
+                           psU32 maskVal,
+                           psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 countInt = 0;           // # of data points being used
+    psF32 countFloat = 0.0;     // # of data points being used
+    psF32 mean = 0.0;           // The mean
+    psF32 diff = 0.0;           // Used in calculating stdev
+    psF32 sumSquares = 0.0;     // temporary variable
+    psF32 sumDiffs = 0.0;       // temporary variable
+    //    psF32 sum1;
+    //    psF32 sum2;
+    psF32 errorDivisor;
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, errors, maskVector, maskVal, stats);
+    }
+    // If the mean is NAN, then generate a warning and set the stdev to NAN.
+    if (0 != isnan(stats->sampleMean)) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): p_psVectorSampleMean() reported a NAN mean.\n");
+        return;
+    }
+
+    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]) &&
+                        (stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((stats->min <= myVector->data.F32[i]) &&
+                        (myVector->data.F32[i] <= stats->max)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+            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++;
+                    if (errors != NULL) {
+                        errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares += (diff * diff);
+                sumDiffs += diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+            if (errors != NULL) {
+                errorDivisor+= (1.0 / PS_SQR(errors->data.F32[i]));
+            }
+        }
+    }
+
+    if (countInt == 0) {
+        stats->sampleStdev = NAN;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): no valid psVector elements (%d).  Setting stats->sampleStdev = NAN.\n", countInt);
+    } else if (countInt == 1) {
+        stats->sampleStdev = 0.0;
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: p_psVectorSampleStdev(): only one valid psVector elements (%d).  Setting stats->sampleStdev = 0.0.\n", countInt);
+    } else {
+        // XXX: The ADD specifies this as the definition of the standard
+        // deviation if the errors are known.  Verify this with IfA: none of
+        // the data points in the vector are used.  Verify that the masks and
+        // data ranges are used correctly.
+        if (errors != NULL) {
+            stats->sampleStdev = (1.0 / PS_SQRT_F32(errorDivisor));
+        } else {
+            countFloat = (psF32)countInt;
+            stats->sampleStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+        }
+    }
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, errors, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    0 for success.
+    -1: error
+    -2: warning
+ *****************************************************************************/
+psS32 p_psVectorClippedStats(const psVector* restrict myVector,
+                             const psVector* restrict errors,
+                             const psVector* restrict maskVector,
+                             psU32 maskVal,
+                             psStats* stats)
+{
+    psS32 i = 0;                  // Loop index variable
+    psS32 j = 0;                  // Loop index variable
+    psF32 clippedMean = 0.0;    // self-explanatory
+    psF32 clippedStdev = 0.0;   // self-explanatory
+    psF32 oldStanMean = 0.0;    // Temporary variable
+    psF32 oldStanStdev = 0.0;   // Temporary variable
+    psVector* tmpMask = NULL;   // Temporary vector
+
+    // Ensure that stats->clipIter is within the proper range.
+    PS_INT_CHECK_RANGE(stats->clipIter,
+                       PS_CLIPPED_NUM_ITER_LB,
+                       PS_CLIPPED_NUM_ITER_UB, -1);
+
+    // Ensure that stats->clipSigma is within the proper range.
+    PS_INT_CHECK_RANGE(stats->clipSigma,
+                       PS_CLIPPED_SIGMA_LB,
+                       PS_CLIPPED_SIGMA_UB, -1);
+
+    // 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);
+
+    // 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.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+    if (isnan(stats->sampleMedian)) {
+        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleMedian returned NAN\n");
+        stats->clippedMean = NAN;
+        stats->clippedStdev = NAN;
+        return(-2);
+    }
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, errors, maskVector, maskVal, stats);
+    if (isnan(stats->sampleStdev)) {
+        psLogMsg(__func__, PS_LOG_WARN, "Call to p_psVectorSampleStdev returned NAN\n");
+        stats->clippedMean = NAN;
+        stats->clippedStdev = NAN;
+        return(-2);
+    }
+
+    // 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++) {
+        // a) Exclude all values x_i for which |x_i - x| > K * stdev
+        if (errors != NULL) {
+            for (j = 0; j < myVector->n; j++) {
+                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * errors->data.F32[j])) {
+                    tmpMask->data.U8[i] = 0xff;
+                }
+            }
+        } else {
+            for (j = 0; j < myVector->n; j++) {
+                if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
+                    tmpMask->data.U8[i] = 0xff;
+                }
+            }
+        }
+
+        // b) compute new mean and stdev
+        p_psVectorSampleMean(myVector, errors, tmpMask, maskVal, stats);
+        p_psVectorSampleStdev(myVector, errors, tmpMask, maskVal, stats);
+
+        // If the new mean and stdev are not NAN, then we use them.
+        // Otherwise, keep the old ones, and exit the loop.
+        if (! (isnan(stats->sampleMean) || isnan(stats->sampleStdev))) {
+            clippedMean = stats->sampleMean;
+            clippedStdev = stats->sampleStdev;
+
+            // Exit loop
+            i = stats->clipIter;
+        }
+    }
+
+    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);
+    return(0);
+}
+
+/*****************************************************************************
+These macros and functions define the following functions:
+ 
+    p_psNormalizeVectorRange(myData, low, high)
+ 
+That assumes that the low/high arguments are PS_TYPE_F64; the vector myData
+can be of any type.  Arguments low/high will be converted to the appropriate
+type and one of the type-specific functions below will be called:
+ 
+    p_psNormalizeVectorRangeU8(myData, low, high)
+    p_psNormalizeVectorRangeU16(myData, low, high)
+    p_psNormalizeVectorRangeU32(myData, low, high)
+    p_psNormalizeVectorRangeU64(myData, low, high)
+    p_psNormalizeVectorRangeS8(myData, low, high)
+    p_psNormalizeVectorRangeS16(myData, low, high)
+    p_psNormalizeVectorRangeS32(myData, low, high)
+    p_psNormalizeVectorRangeS64(myData, low, high)
+    p_psNormalizeVectorRangeF32(myData, low, high)
+    p_psNormalizeVectorRangeF64(myData, low, high)
+ *****************************************************************************/
+#define PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(TYPE) \
+void p_psNormalizeVectorRange##TYPE(psVector* myData, \
+                                    ps##TYPE outLow, \
+                                    ps##TYPE outHigh) \
+{ \
+    ps##TYPE min = (ps##TYPE) PS_MAX_##TYPE; \
+    ps##TYPE max = (ps##TYPE) -PS_MAX_##TYPE; \
+    psS32 i = 0; \
+    \
+    for (i = 0; i < myData->n; i++) { \
+        if (myData->data.TYPE[i] < min) { \
+            min = myData->data.TYPE[i]; \
+        } \
+        if (myData->data.TYPE[i] > max) { \
+            max = myData->data.TYPE[i]; \
+        } \
+    } \
+    \
+    /* Ensure that max!=min before we divide by (max-min) */ \
+    if (max != min) { \
+        for (i = 0; i < myData->n; i++) { \
+            myData->data.TYPE[i] = (outLow + (myData->data.TYPE[i] - min) * \
+                                    (outHigh - outLow) / (max - min)); \
+        } \
+    } else { \
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: (max==min).  Setting all elements to min.\n"); \
+        for (i = 0; i < myData->n; i++) \
+        { \
+            \
+            myData->data.TYPE[i] = outLow; \
+            \
+        } \
+    } \
+} \
+
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U8)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U16)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U64)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S8)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S16)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(S64)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F32)
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(F64)
+
+void p_psNormalizeVectorRange(psVector* myData,
+                              psF64 outLow,
+                              psF64 outHigh)
+{
+    switch (myData->type.type) {
+    case PS_TYPE_U8:
+        p_psNormalizeVectorRangeU8(myData, (psU8) outLow, (psU8) outHigh);
+        break;
+    case PS_TYPE_U16:
+        p_psNormalizeVectorRangeU16(myData, (psU16) outLow, (psU16) outHigh);
+        break;
+    case PS_TYPE_U32:
+        p_psNormalizeVectorRangeU32(myData, (psU32) outLow, (psU32) outHigh);
+        break;
+    case PS_TYPE_U64:
+        p_psNormalizeVectorRangeU64(myData, (psU64) outLow, (psU64) outHigh);
+        break;
+    case PS_TYPE_S8:
+        p_psNormalizeVectorRangeS8(myData, (psS8) outLow, (psS8) outHigh);
+        break;
+    case PS_TYPE_S16:
+        p_psNormalizeVectorRangeS16(myData, (psS16) outLow, (psS16) outHigh);
+        break;
+    case PS_TYPE_S32:
+        p_psNormalizeVectorRangeS32(myData, (psS32) outLow, (psS32) outHigh);
+        break;
+    case PS_TYPE_S64:
+        p_psNormalizeVectorRangeS64(myData, (psS64) outLow, (psS64) outHigh);
+        break;
+    case PS_TYPE_F32:
+        p_psNormalizeVectorRangeF32(myData, (psF32) outLow, (psF32) outHigh);
+        break;
+    case PS_TYPE_F64:
+        p_psNormalizeVectorRangeF64(myData, (psF64) outLow, (psF64) outHigh);
+        break;
+    case PS_TYPE_C32:
+    case PS_TYPE_C64:
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                "Unallowable operation: %s has incorrect type.",
+                myData);
+        break;
+    }
+}
+
+/******************************************************************************
+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.
+ 
+XXX: Create a 2nd-order polynomial version and solve for X analytically.
+ *****************************************************************************/
+psF32 p_ps1DPolyMedian(psPolynomial1D* myPoly,
+                       psF32 rangeLow,
+                       psF32 rangeHigh,
+                       psF32 getThisValue)
+{
+    PS_POLY_CHECK_NULL(myPoly, NAN);
+    PS_FLOAT_COMPARE(rangeLow, rangeHigh, NAN);
+    // We ensure that the requested f(y) value, which is getThisValue, is
+    // falls within the range of y-values of the polynomial "myPoly" in the
+    // specified x-range (rangeLow:rangeHigh).
+    psF32 fLo = psPolynomial1DEval(
+                    myPoly,
+                    rangeLow
+                );
+    psF32 fHi = psPolynomial1DEval(
+                    myPoly,
+                    rangeHigh
+                );
+    if (!((fLo <= getThisValue) && (fHi >= getThisValue))) {
+        psError(PS_ERR_UNKNOWN,
+                true,
+                PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE);
+        return(NAN);
+    }
+
+    psS32 numIterations = 0;
+    psF32 midpoint = 0.0;
+    psF32 oldMidpoint = 1.0;
+    psF32 f = 0.0;
+
+    while (numIterations < PS_POLY_MEDIAN_MAX_ITERATIONS) {
+        midpoint = (rangeHigh + rangeLow) / 2.0;
+        if (fabs(midpoint - oldMidpoint) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+        oldMidpoint = midpoint;
+
+        f = psPolynomial1DEval(
+                myPoly,
+                midpoint
+            );
+        if (fabs(f - getThisValue) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+
+        if (f > getThisValue) {
+            rangeHigh = midpoint;
+        } else {
+            rangeLow = midpoint;
+        }
+        numIterations++;
+    }
+    return (midpoint);
+}
+
+/******************************************************************************
+fitQuadraticSearchForYThenReturnX(*xVec, *yVec, binNum, yVal): A general
+routine which fits a quadratic to three points and returns the x-value
+corresponding to the input y-value.  This routine takes psVectors of x/y pairs
+as input, and fits a quadratic to the 3 points surrounding element binNum in
+the vectors (the midpoint between element i and i+1 is used for x[i]).  It
+then determines for what value x does that quadratic f(x) = yVal (the input
+parameter).
+ 
+XXX: After you fit the polynomial, solve for X analytically.
+ 
+XXX: the vectors do not have to be the same length.  Must insert the proper
+tests to ensure that binNum is within acceptable ranges for both vectors.
+*****************************************************************************/
+psF32 fitQuadraticSearchForYThenReturnX(psVector *xVec,
+                                        psVector *yVec,
+                                        psS32 binNum,
+                                        psF32 yVal)
+{
+    PS_VECTOR_CHECK_NULL(xVec, NAN);
+    PS_VECTOR_CHECK_NULL(yVec, NAN);
+    PS_VECTOR_CHECK_TYPE(xVec, PS_TYPE_F32, NAN);
+    PS_VECTOR_CHECK_TYPE(yVec, PS_TYPE_F32, NAN);
+    //    PS_VECTOR_CHECK_SIZE_EQUAL(xVec, yVec, NAN);
+    PS_INT_CHECK_RANGE(binNum, 0, (xVec->n - 1), NAN);
+    PS_INT_CHECK_RANGE(binNum, 0, (yVec->n - 1), NAN);
+
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(x, 3, PS_TYPE_F64);
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(y, 3, PS_TYPE_F64);
+    //    PS_VECTOR_DECLARE_ALLOC_STATIC(yErr, 3, PS_TYPE_F64);
+    //    PS_POLY_1D_DECLARE_ALLOC_STATIC(myPoly, 2, PS_POLYNOMIAL_ORD);
+    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);
+
+    psF32 tmpFloat;
+
+    if ((binNum > 0) && (binNum < (yVec->n - 2))) {
+        // The general case.  We have all three points.
+        x->data.F64[0] = (psF64) (0.5 * (xVec->data.F32[binNum - 1] + xVec->data.F32[binNum]));
+        x->data.F64[1] = (psF64) (0.5 * (xVec->data.F32[binNum] + xVec->data.F32[binNum+1]));
+        x->data.F64[2] = (psF64) (0.5 * (xVec->data.F32[binNum+1] + xVec->data.F32[binNum+2]));
+        y->data.F64[0] = yVec->data.F32[binNum - 1];
+        y->data.F64[1] = yVec->data.F32[binNum];
+        y->data.F64[2] = yVec->data.F32[binNum + 1];
+
+        // Ensure that yVal is within the range of the bins we are using.
+        if (!((y->data.F64[0] <= yVal) && (yVal <= y->data.F64[2]))) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE,
+                    (psF64)yVal,y->data.F64[2],y->data.F64[0]);
+        }
+        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);
+        if (myPoly == NULL) {
+            psError(PS_ERR_UNEXPECTED_NULL,
+                    false,
+                    PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT);
+            psFree(myPoly);
+            psFree(x);
+            psFree(y);
+            psFree(yErr);
+            return(NAN);
+        }
+        // Call p_ps1DPolyMedian(), which does a binary search on the
+        // polynomial, looking for the value x such that f(x) = yVal
+        tmpFloat = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], yVal);
+        if (isnan(tmpFloat)) {
+            psError(PS_ERR_UNEXPECTED_NULL,
+                    false,
+                    PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN);
+            psFree(myPoly);
+            psFree(x);
+            psFree(y);
+            psFree(yErr);
+            return(NAN);
+        }
+
+    } else {
+        // The special case where we have two points only at the beginning of
+        // the vectors x and y.
+        if (binNum == 0) {
+            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
+                              xVec->data.F32[binNum + 1]);
+        } else if (binNum == (xVec->n - 1)) {
+            // The special case where we have two points only at the end of
+            // the vectors x and y.
+            // XXX: Is this right?
+            tmpFloat = xVec->data.F32[binNum];
+        } else if (binNum == (xVec->n - 2)) {
+            // XXX: Is this right?
+            tmpFloat = 0.5 * (xVec->data.F32[binNum] +
+                              xVec->data.F32[binNum + 1]);
+        }
+    }
+
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    return(tmpFloat);
+}
+
+/******************************************************************************
+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.).
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    0 on success.
+ 
+XXX: Check for errors in psLib routines that we call.
+*****************************************************************************/
+psS32 p_psVectorRobustStats(const psVector* restrict myVector,
+                            const psVector* restrict errors,
+                            const psVector* restrict maskVector,
+                            psU32 maskVal,
+                            psStats* stats)
+{
+    psHistogram* robustHistogram = NULL;
+    psVector* robustHistogramVector = NULL;
+    psF32 binSize = 0.0;        // Size of the histogram bins
+    psS32 LQBinNum = -1;          // Bin num for lower quartile
+    psS32 UQBinNum = -1;          // Bin num for upper quartile
+    psS32 medianBinNum = -1;
+    psS32 i = 0;                  // Loop index variable
+    psS32 modeBinNum = 0;
+    psF32 modeBinCount = 0.0;
+    psF32 dL = 0.0;
+    psS32 numBins = 0;
+    psF32 myMean = 0.0;
+    psF32 myStdev = 0.0;
+    psF32 countFloat = 0.0;
+    psF32 diff = 0.0;
+    psF32 sumSquares = 0.0;
+    psF32 sumDiffs = 0.0;
+    psVector* cumulativeRobustSums = NULL;
+    psF32 sumRobust = 0.0;
+    psF32 sumN50 = 0.0;
+    psF32 sumNfit = 0.0;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+    psStats* tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV | PS_STAT_CLIPPED_MEAN);
+
+    // 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;
+    //XXX: add errors
+    psS32 rc = p_psVectorClippedStats(myVector, NULL, maskVector, maskVal, tmpStats);
+    if (rc != 0) {
+        psError(PS_ERR_UNEXPECTED_NULL,
+                false,
+                PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS);
+        return(1);
+    }
+    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(0);
+    }
+
+    // Determine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        if (0 != p_psVectorMin(myVector, maskVector, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: p_psVectorMin(): p_psVectorMin() reported a NAN mean.\n");
+            return(1);
+        }
+    }
+    if (isnan(stats->max)) {
+        if (0 != p_psVectorMax(myVector, maskVector, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: p_psVectorMin(): p_psVectorMax() reported a NAN mean.\n");
+            return(1);
+        }
+    }
+
+    // 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 = (psS32)((stats->max - stats->min) / binSize);
+    robustHistogram = psHistogramAlloc(stats->min, stats->max, numBins);
+
+    // Populate the histogram array.
+    psVectorHistogram(robustHistogram, myVector, errors, maskVector, maskVal);
+
+    // Smooth the histogram, Gaussian-style.
+    robustHistogramVector = p_psVectorSmoothHistGaussian(robustHistogram,
+                            tmpStats->clippedStdev / 4.0f);
+
+    /**************************************************************************
+    Determine the median/lower/upper quartile bin numbers.
+
+    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 in
+    determining the median and lower/upper quartiles.
+    **************************************************************************/
+    cumulativeRobustSums = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    cumulativeRobustSums->data.F32[0] = robustHistogramVector->data.F32[0];
+    for (i = 1; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSums->data.F32[i] = cumulativeRobustSums->data.F32[i - 1] +
+                                            robustHistogramVector->data.F32[i];
+    }
+    sumRobust = cumulativeRobustSums->data.F32[robustHistogramVector->n - 1];
+
+    tmpScalar.data.F32 = sumRobust / 4.0;
+    LQBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+    tmpScalar.data.F32 = 3.0 * sumRobust / 4.0;
+    UQBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+    tmpScalar.data.F32 = sumRobust / 2.0;
+    medianBinNum = p_psVectorBinDisect(cumulativeRobustSums, &tmpScalar);
+
+    if ((LQBinNum < 0) || (UQBinNum < 0)) {
+        psError(PS_ERR_UNKNOWN, true,
+                PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED);
+        return(1);
+    }
+    if (medianBinNum < 0) {
+        psError(PS_ERR_UNKNOWN, true,
+                PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED);
+        return(1);
+    }
+    /**************************************************************************
+    Determine the mode in the range LQ:UQ.
+    **************************************************************************/
+    // Determine the bin with the peak value in the range LQ to UQ.
+    modeBinNum = LQBinNum;
+    modeBinCount = robustHistogramVector->data.F32[LQBinNum];
+    sumN50 = robustHistogram->nums->data.F32[LQBinNum];
+    for (i = LQBinNum + 1; i <= UQBinNum; i++) {
+        if (robustHistogramVector->data.F32[i] > modeBinCount) {
+            modeBinNum = i;
+            modeBinCount = robustHistogramVector->data.F32[i];
+        }
+        sumN50 += robustHistogram->nums->data.F32[i];
+    }
+
+    dL = (UQBinNum - LQBinNum) / 4;
+    /**************************************************************************
+    Determine the mean/stdev for the bins in the range mode-dL to mode+dL
+    **************************************************************************/
+    // 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).
+    sumNfit = 0.0;
+    myMean = 0.0;
+    for (i = modeBinNum - dL; i <= modeBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            myMean += (robustHistogramVector->data.F32[i]) * PS_BIN_MIDPOINT(robustHistogram, i);
+            countFloat += robustHistogramVector->data.F32[i];
+        }
+
+        sumNfit += robustHistogram->nums->data.F32[i];
+    }
+    // XXX: divide by zero?
+    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 = modeBinNum - dL; i <= modeBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            diff = PS_BIN_MIDPOINT(robustHistogram, i) - myMean;
+            sumSquares += diff * diff * robustHistogramVector->data.F32[i];
+            sumDiffs += diff * robustHistogramVector->data.F32[i];
+        }
+    }
+    myStdev = PS_SQRT_F32((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+    // Using the above (myMean, myStdev) as initial estimates, we fit a
+    // Gaussian to the robustHistogramVector.
+    psMinimization *min = psMinimizationAlloc(100, 0.1);
+    psVector *myParams = psVectorAlloc(2, PS_TYPE_F32);
+    psArray *myCoords = psArrayAlloc(robustHistogramVector->n);
+    psVector *y = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+
+    p_psNormalizeVectorRangeF32(robustHistogramVector, 0.0, 1.0);
+    for (i=0;i<robustHistogramVector->n;i++) {
+        myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (psF32) i;
+        y->data.F32[i] = robustHistogramVector->data.F32[i];
+    }
+
+    myParams->data.F32[0] = myMean;
+    myParams->data.F32[1] = myStdev;
+    psImage *covar = NULL;
+    psMinimizeLMChi2(min,
+                     NULL,
+                     myParams,
+                     NULL,
+                     myCoords,
+                     y,
+                     NULL,
+                     (psMinimizeLMChi2Func) psMinimizeLMChi2Gauss1D);
+    psFree(covar);
+    psFree(min);
+    psFree(myParams);
+    psFree(myCoords);
+    psFree(y);
+    /**************************************************************************
+    Set the appropriate members in the output stats struct.
+    **************************************************************************/
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        if (fabs((myParams->data.F32[0] - myMean)/myMean) > 0.1) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the fitted Gaussian has more than 10%% error for the mean.\n");
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: Using the calculated mean instead of Gaussian-fitted mean.");
+            //                     "WARNING: Using the calculated mean instead of Gaussian-fitted mean.(calc, fit) is (%f, %f)\n",
+            //                     myMean, myParams->data.F32[0]);
+            stats->robustMean = myMean;
+        } else {
+            stats->robustMean = myParams->data.F32[0];
+        }
+    }
+
+    if (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = PS_BIN_MIDPOINT(robustHistogram, modeBinNum);
+    }
+
+    if (stats->options & PS_STAT_ROBUST_STDEV) {
+        if (fabs((myParams->data.F32[1] - myStdev)/myStdev) > 0.1) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the fitted Gaussian has more than 10%% error for the stdev.\n");
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: Using the calculated stdev instead of Gaussian-fitted stdev.");
+            //                     "WARNING: Using the calculated stdev instead of Gaussian-fitted stdev.(calc, fit) is (%f, %f)\n",
+            //                     myStdev, myParams->data.F32[1]);
+            stats->robustStdev = myStdev;
+        } else {
+            stats->robustStdev = myParams->data.F32[1];
+        }
+    }
+
+    // To determine the median, we fit a quadratic y=f(x) to the three bins
+    // surrounding the bin containing the median (x is the midpoint of each
+    // bin and y is the value of each bin).  Then we figure out what value
+    // of x corresponds to f(x) being the median (half of all points).
+    if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        // Take a psVector.  Fit a polynomial y = f(x) to the 3 data elements
+        // surrounding medianBinNum, then find the x-value corresponding y = sumRobust/2.0.
+
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustMedian = fitQuadraticSearchForYThenReturnX(
+                                  robustHistogram->bounds,
+                                  cumulativeRobustSums,
+                                  medianBinNum,
+                                  sumRobust/2.0);
+    }
+
+    // To determine the quartiles, we fit a quadratic y=f(x) to the three bins
+    // surrounding the bin containing LQ/UQ (x is the midpoint of each
+    // bin and y is the value of each bin).  Then we figure out what value
+    // of x corresponds to f(x) being the LQ/UQ.
+    if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        countFloat = cumulativeRobustSums->data.F32[robustHistogramVector->n - 1];
+
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustLQ = fitQuadraticSearchForYThenReturnX(
+                              robustHistogram->bounds,
+                              cumulativeRobustSums,
+                              LQBinNum,
+                              countFloat/4.0);
+        //XXX: robustHistogram->bounds and cumulativeRobustSums are of different lengths.
+        //Determine id that is okay.
+        stats->robustUQ = fitQuadraticSearchForYThenReturnX(
+                              robustHistogram->bounds,
+                              cumulativeRobustSums,
+                              UQBinNum,
+                              3.0 * countFloat/4.0);
+    }
+    // XXX: I think sumNfit == sumN50 here.
+    stats->robustNfit = sumNfit;
+    stats->robustN50 = sumN50;
+
+    psFree(tmpStats);
+    psFree(robustHistogram);
+    psFree(robustHistogramVector);
+    psFree(cumulativeRobustSums);
+    return(0);
+}
+
+/*****************************************************************************/
+
+/* 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(psF32 lower, psF32 upper, psS32 n)
+{
+    PS_INT_CHECK_POSITIVE(n, NULL);
+    PS_FLOAT_COMPARE(lower, upper, NULL);
+
+    psS32 i = 0;                  // Loop index variable
+    psHistogram* newHist = NULL;        // The new histogram structure
+    psF32 binSize = 0.0;        // The histogram bin size
+
+    // 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) / (psF32)n;
+    // XXX: 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 * (psF32)i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums = psVectorAlloc(n, PS_TYPE_F32);
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.F32[i] = 0.0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return (newHist);
+}
+
+/******************************************************************************
+psHistogramAllocGeneric(bounds): allocate a non-uniform histogram structure
+with the specifed bounds.
+ 
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAllocGeneric(const psVector* restrict bounds)
+{
+    PS_VECTOR_CHECK_NULL(bounds, NULL);
+    PS_VECTOR_CHECK_TYPE(bounds, PS_TYPE_F32, NULL);
+    PS_INT_COMPARE(2, bounds->n, NULL);
+
+    psHistogram* newHist = NULL;        // The new histogram structure
+    psS32 i;                      // Loop index variable
+
+    // 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_F32);
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.F32[i] = 0.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);
+}
+
+/*****************************************************************************
+UpdateHistogramBins(binNum, out, data, error): This routine is to be used when
+updating the histogram in the presence of errors in the input data.  We treat
+the data point as a boxcar PDF and update a range of points surrounding the
+histogram bin which contains the point.  The width of that boxcar is defined
+as 2.35 * error.  Inputs:
+    binNum: the bin number of the data point in the histogram
+    out: the histogram structure
+    data: the data point value
+    error: the error in that data point
+ 
+XXX: Must test this.
+ *****************************************************************************/
+psS32 UpdateHistogramBins(psS32 binNum,
+                          psHistogram* out,
+                          psF32 data,
+                          psF32 error)
+{
+    PS_PTR_CHECK_NULL(out, -1);
+    PS_PTR_CHECK_NULL(out->bounds, -1);
+    PS_PTR_CHECK_NULL(out->nums, -1);
+    PS_INT_CHECK_RANGE(binNum, 0, ((out->nums->n)-1), -2);
+    PS_FLOAT_COMPARE(0.0, error, -3);
+    PS_FLOAT_CHECK_RANGE(data, out->bounds->data.F32[0], out->bounds->data.F32[(out->bounds->n)-1], -4);
+
+    psF32 boxcarWidth = 2.35 * error;
+    psF32 boxcarCenter = (out->bounds->data.F32[binNum] +
+                          out->bounds->data.F32[binNum+1]) / 2.0;
+    psF32 boxcarLeft = boxcarCenter - (boxcarWidth / 2.0);
+    psF32 boxcarRight = boxcarCenter + (boxcarWidth / 2.0);
+    psS32 bin;
+    psS32 boxcarLeftBinNum;
+    psS32 boxcarRightBinNum;
+
+    // Determine the left endpoint of the boxcar for the PDF.
+    for (bin=binNum ; bin >= 0 ; bin--) {
+        if (out->nums->data.F32[bin] <= boxcarLeft) {
+            boxcarLeftBinNum = bin;
+            break;
+        }
+    }
+
+    // Determine the right endpoint of the boxcar for the PDF.
+    for (bin=binNum ; bin < out->nums->n ; bin++) {
+        if (out->nums->data.F32[bin] >= boxcarRight) {
+            boxcarRightBinNum = bin;
+            break;
+        }
+    }
+
+    //
+    // If the boxcar fits entirely inside this bin, then simply add 1.0 to the
+    // bin and return.
+    //
+    if (boxcarLeftBinNum == boxcarRightBinNum) {
+        out->nums->data.F32[binNum]+= 1.0;
+        return(0);
+    }
+
+    //
+    // If we get here, multiple bins must be updated.  We handle the left
+    // endpoint, and right endpoint differently.
+    //
+    out->nums->data.F32[boxcarLeftBinNum]+=
+        (out->bounds->data.F32[boxcarLeftBinNum+1] - boxcarLeft) / boxcarWidth;
+
+    //
+    // Loop through the center bins, if any.
+    //
+    for (bin = boxcarLeftBinNum + 1 ; bin < (boxcarRightBinNum - 1) ; bin++) {
+        out->nums->data.F32[bin]+=
+            (out->bounds->data.F32[bin+1] - out->bounds->data.F32[bin]) / boxcarWidth;
+    }
+
+    //
+    // Handle the right endpoint differently.
+    //
+    out->nums->data.F32[boxcarRightBinNum]+=
+        (boxcarRight - out->bounds->data.F32[boxcarRightBinNum]) / boxcarWidth;
+
+    //
+    // Return 0 on success.
+    //
+    return(0);
+}
+
+
+/*****************************************************************************
+psVectorHistogram(out, in, errors, 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 errors,
+                               const psVector* restrict mask,
+                               psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(out, NULL);
+    PS_VECTOR_CHECK_NULL(out->bounds, NULL);
+    PS_VECTOR_CHECK_TYPE(out->bounds, PS_TYPE_F32, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(out->bounds->n, NULL);
+    PS_VECTOR_CHECK_NULL(out->nums, NULL);
+    PS_VECTOR_CHECK_TYPE(out->nums, PS_TYPE_F32, NULL);
+    PS_INT_CHECK_NON_NEGATIVE(out->nums->n, NULL);
+    PS_VECTOR_CHECK_NULL(in, out);
+    if (mask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(in, mask, NULL);
+        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, NULL);
+    }
+    if (errors != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(in, errors, NULL);
+        PS_VECTOR_CHECK_TYPE(errors, in->type.type, NULL);
+    }
+
+    psS32 i = 0;                  // Loop index variable
+    psF32 binSize = 0.0;          // Histogram bin size
+    psS32 binNum = 0;             // A temporary bin number
+    psS32 numBins = 0;            // The total number of bins
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+    psVector* inF32 = NULL;
+    psVector* errorsF32 = NULL;
+    psS32 mustFreeVectorIn = 1;
+    psS32 mustFreeVectorErrors = 1;
+
+    // Convert input and errors vectors to F32 if necessary.
+    inF32 = p_psConvertToF32((psVector *) in);
+    if (inF32 == NULL) {
+        inF32 = (psVector *) in;
+        mustFreeVectorIn = 0;
+    }
+    errorsF32 = p_psConvertToF32((psVector *) errors);
+    if (errorsF32 == NULL) {
+        errorsF32 = (psVector *) errors;
+        mustFreeVectorErrors = 0;
+    }
+
+    numBins = out->nums->n;
+    for (i = 0; i < inF32->n; i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) || ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            if (inF32->data.F32[i] < out->bounds->data.F32[0]) {
+                // If this pixel is below minimum value, count it, then skip.
+                out->minNum++;
+            } else if (inF32->data.F32[i] > out->bounds->data.F32[numBins]) {
+                // If this pixel is above maximum value, count it, then skip.
+                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 = (psS32)((inF32->data.F32[i] - out->bounds->data.F32[0]) / binSize);
+                    if (errorsF32 != NULL) {
+                        // XXX: Check return codes.
+                        UpdateHistogramBins(binNum, out,
+                                            inF32->data.F32[i],
+                                            errorsF32->data.F32[i]);
+                    } else {
+                        // XXX: This if-statement really shouldn't be necessary.
+                        // However, due to numerical lack of precision, we
+                        // occasionally produce a binNum outside the range.
+                        if (binNum >= out->nums->n) {
+                            binNum = out->nums->n - 1;
+                        }
+                        (out->nums->data.F32[binNum])+= 1.0;
+                    }
+
+                } else {
+                    // If this is a non-uniform histogram, determining the
+                    // correct bin number requires a bit more work.
+                    tmpScalar.data.F32 = inF32->data.F32[i];
+                    binNum = p_psVectorBinDisect(out->bounds, &tmpScalar);
+                    if (binNum < 0) {
+                        psLogMsg(__func__, PS_LOG_WARN,
+                                 "WARNING: psVectorHistogram(): element outside histogram bounds.\n");
+                    } else {
+                        if (errorsF32 != NULL) {
+                            // XXX: Check return codes.
+                            UpdateHistogramBins(binNum, out,
+                                                inF32->data.F32[i],
+                                                errors->data.F32[i]);
+                        } else {
+                            (out->nums->data.F32[binNum])+= 1.0;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (mustFreeVectorIn == 1) {
+        psFree(inF32);
+    }
+    if (mustFreeVectorErrors == 1) {
+        psFree(errorsF32);
+    }
+    return (out);
+}
+
+/******************************************************************************
+p_psConvertToF32(in): 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 Opterons...
+ *****************************************************************************/
+psVector* p_psConvertToF32(psVector* in)
+{
+    if (in == NULL) {
+        return(NULL);
+    }
+    psS32 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] = (psF32)in->data.S8[i];
+        }
+    } else if (in->type.type == PS_TYPE_S16) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32) in->data.S16[i];
+        }
+    } else if (in->type.type == PS_TYPE_S32) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.S32[i];
+        }
+    } else if (in->type.type == PS_TYPE_S64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.S64[i];
+        }
+    } else if (in->type.type == PS_TYPE_U8) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U8[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] = (psF32)in->data.U16[i];
+        }
+    } else if (in->type.type == PS_TYPE_U32) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U32[i];
+        }
+    } else if (in->type.type == PS_TYPE_U64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (psF32)in->data.U64[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] = (psF32)in->data.F64[i];
+        }
+    } else if (in->type.type == PS_TYPE_F32) {
+        // do nothing
+    } else {
+        psS8* strType;
+        PS_TYPE_NAME(strType, in->type.type);
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED,
+                strType);
+    }
+    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.
+ *****************************************************************************/
+psStats* psVectorStats(psStats* stats,
+                       psVector* in,
+                       psVector* errors,
+                       psVector* mask,
+                       psU32 maskVal)
+{
+    PS_PTR_CHECK_NULL(stats, NULL);
+    PS_VECTOR_CHECK_NULL(in, stats);
+    if (mask != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(mask, in, stats);
+        PS_VECTOR_CHECK_TYPE(mask, PS_TYPE_U8, stats);
+    }
+    if (errors != NULL) {
+        PS_VECTOR_CHECK_SIZE_EQUAL(errors, in, stats);
+        PS_VECTOR_CHECK_TYPE(errors, in->type.type, stats);
+    }
+
+    psVector* inF32 = NULL;
+    psVector* errorsF32 = NULL;
+    psS32 mustFreeVectorIn = 1;
+    psS32 mustFreeVectorErrors = 1;
+
+    inF32 = p_psConvertToF32((psVector *) in);
+    if (inF32 == NULL) {
+        inF32 = in;
+        mustFreeVectorIn = 0;
+    }
+    errorsF32 = p_psConvertToF32((psVector *) errors);
+    if (errorsF32 == NULL) {
+        errorsF32 = errors;
+        mustFreeVectorErrors = 0;
+    }
+
+    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
+        PS_FLOAT_COMPARE(stats->min, stats->max, stats);
+    }
+
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        if (false == p_psVectorSampleMedian(inF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMedian() returned an error.\n");
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        if (0 != p_psVectorSampleMean(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleMean() returned an error.\n");
+        }
+        p_psVectorSampleStdev(inF32, errorsF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        if (false == p_psVectorSampleQuartiles(inF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: psVectorStats(): p_psVectorSampleQuartiles() returned an error.\n");
+        }
+    }
+    // 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)) {
+        if (0 != p_psVectorRobustStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psStats_STATS_FAILED);
+            // XXX: Set to NAN
+        }
+    }
+
+    // XXX: Different conditions for return -1 and -2?
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        if (-1 >  p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate clipped statistics for input psVector.\n");
+            stats->clippedMean = NAN;
+            stats->clippedStdev = NAN;
+        } else if (-2 == p_psVectorClippedStats(inF32, errorsF32, mask, maskVal, stats)) {
+            psLogMsg(__func__, PS_LOG_WARN, "Failed to calculate clipped statistics for input psVector.");
+            stats->clippedMean = NAN;
+            stats->clippedStdev = NAN;
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        if (0 != p_psVectorMax(inF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate vector maximum");
+            psFree(stats);
+            return(NULL);
+        }
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        if (0 != p_psVectorMin(inF32, mask, maskVal, stats)) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to calculate vector minimum");
+            psFree(stats);
+            return(NULL);
+        }
+    }
+
+    if (mustFreeVectorIn == 1) {
+        psFree(inF32);
+    }
+    if (mustFreeVectorErrors == 1) {
+        psFree(errorsF32);
+    }
+    return (stats);
+}
+
Index: /branches/rel4/psLib/src/math/psStats.h
===================================================================
--- /branches/rel4/psLib/src/math/psStats.h	(revision 3057)
+++ /branches/rel4/psLib/src/math/psStats.h	(revision 3057)
@@ -0,0 +1,191 @@
+
+/** @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.37 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-22 05:09:32 $
+ *
+ *  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
+{
+    psF64 sampleMean;          ///< formal mean of sample
+    psF64 sampleMedian;        ///< formal median of sample
+    psF64 sampleStdev;         ///< standard deviation of sample
+    psF64 sampleUQ;            ///< upper quartile of sample
+    psF64 sampleLQ;            ///< lower quartile of sample
+    psF64 robustMean;          ///< robust mean of array
+    psF64 robustMedian;        ///< robust median of array
+    psF64 robustMode;          ///< Robust mode of array
+    psF64 robustStdev;         ///< robust standard deviation of array
+    psF64 robustUQ;            ///< robust upper quartile
+    psF64 robustLQ;            ///< robust lower quartile
+    psS32 robustN50;              ///<
+    psS32 robustNfit;             ///<
+    psF64 clippedMean;         ///< Nsigma clipped mean
+    psF64 clippedStdev;        ///< standard deviation after clipping
+    psS32 clippedNvalues;         ///< ???
+    psF64 clipSigma;           ///< Nsigma used for clipping; user input
+    psS32 clipIter;               ///< Number of clipping iterations; user input
+    psF64 min;                 ///< minimum data value in array
+    psF64 max;                 ///< maximum data value in array
+    psF64 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.
+    psVector* errors,  ///< Errors.
+    psVector* mask,    ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+    psU32 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)
+    psS32 minNum;                        ///< Number below the minimum
+    psS32 maxNum;                        ///< Number above the maximum
+    psBool 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(
+    psF32 lower,                       ///< Lower limit for the bins
+    psF32 upper,                       ///< Upper limit for the bins
+    psS32 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 errors,   ///< Errors
+    const psVector* restrict mask,     ///< Mask dat for input vector
+    psU32 maskVal               ///< Mask value
+);
+
+/** Extracts the statistic value specified by stats->options.
+ *
+ *  @return psBool    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.
+ */
+psBool p_psGetStatValue(
+    const psStats* stats,
+    ///< the statistic struct to operate on
+
+    psF64 *value
+    ///< if return is true, this is set to the specified statistic value by stats->options
+);
+
+void p_psNormalizeVectorRangeU8(psVector* myData, psU8 low, psU8 high);
+void p_psNormalizeVectorRangeU16(psVector* myData, psU16 low, psU16 high);
+void p_psNormalizeVectorRangeU32(psVector* myData, psU32 low, psU32 high);
+void p_psNormalizeVectorRangeU64(psVector* myData, psU64 low, psU64 high);
+void p_psNormalizeVectorRangeS8(psVector* myData, psS8 low, psS8 high);
+void p_psNormalizeVectorRangeS16(psVector* myData, psS16 low, psS16 high);
+void p_psNormalizeVectorRangeS32(psVector* myData, psS32 low, psS32 high);
+void p_psNormalizeVectorRangeS64(psVector* myData, psS64 low, psS64 high);
+void p_psNormalizeVectorRangeF32(psVector* myData, psF32 low, psF32 high);
+void p_psNormalizeVectorRangeF64(psVector* myData, psF64 low, psF64 high);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/mathtypes/psImage.c
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psImage.c	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psImage.c	(revision 3057)
@@ -0,0 +1,753 @@
+/** @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.57 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 03:26:23 $
+ *
+ *  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 "psString.h"
+
+#include "psImageErrors.h"
+
+static void imageFree(psImage* image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference elements
+        psU32 oldNumRows = image->numRows;
+        psU32 oldNumCols = image->numCols;
+        psPtr* rowPtr;
+
+        for (psU32 row = 0; row < oldNumRows; row++) {
+            rowPtr = image->data.PTR[row];
+            for (psU32 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* psImageAlloc(psU32 numCols,
+                      psU32 numRows,
+                      const psElemType type)
+{
+    psS32 area = 0;
+    psS32 elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    psS32 rowSize = numCols * elementSize;        // row size in bytes.
+
+    area = numCols * numRows;
+
+    if (area < 1) {
+        psError(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(psPtr ) * numRows);
+
+    image->rawDataBuffer = psAlloc(area * elementSize);
+
+    // set the row pointers.
+    image->data.V[0] = image->rawDataBuffer;
+    for (psS32 i = 1; i < numRows; i++) {
+        image->data.V[i] = (psPtr )((int8_t *) image->data.V[i - 1] + rowSize);
+    }
+
+    *(psS32 *)&image->col0 = 0;
+    *(psS32 *)&image->row0 = 0;
+    *(psU32 *)&image->numCols = numCols;
+    *(psU32 *)&image->numRows = numRows;
+    *(psDimen* ) & image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType* ) & image->type.type = type;
+    image->parent = NULL;
+    image->children = NULL;
+
+    return image;
+}
+
+psRegion* psRegionAlloc(psF32 x0,
+                        psF32 x1,
+                        psF32 y0,
+                        psF32 y1)
+{
+    psRegion* out = psAlloc(sizeof(psRegion));
+
+    out->x0 = x0;
+    out->y0 = y0;
+    out->x1 = x1;
+    out->y1 = y1;
+
+    return out;
+}
+
+
+
+psRegion* psRegionFromString(char* region)
+{
+    psS32 col0;
+    psS32 col1;
+    psS32 row0;
+    psS32 row1;
+
+    // section should be of the form '[col0:col1,row0:row1]'
+    if (region == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_SUBSECTION_NULL);
+        return NULL;
+    }
+
+    if (sscanf(region,"[%d:%d,%d:%d]",&col0,&col1,&row0,&row1) < 4) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_SUBSECTION_INVALID,
+                region);
+        return NULL;
+    }
+
+    if (col0 > col1 || row0 > row1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED,
+                col0,col1,row0,row1);
+        return NULL;
+    }
+
+    return psRegionAlloc(col0,col1,row0,row1);
+}
+
+char* psRegionToString(psRegion* region)
+{
+    char tmpText[256]; // big enough to store any region as text
+
+    if (region == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_REGION_NULL);
+        return NULL;
+    }
+
+    snprintf(tmpText,256,"[%g:%g,%g:%g]",
+             region->x0, region->x1,
+             region->y0, region->y1);
+
+    return psStringCopy(tmpText);
+}
+
+
+psImage* psImageRecycle(psImage* old,
+                        psU32 numCols,
+                        psU32 numRows,
+                        const psElemType type)
+{
+    psS32 elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    psS32 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);
+        psError(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
+        psU32 oldNumRows = old->numRows;
+        psU32 oldNumCols = old->numCols;
+        psPtr* rowPtr;
+
+        for (psU32 row = 0; row < oldNumRows; row++) {
+            rowPtr = old->data.PTR[row];
+            for (psU32 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 = (psPtr *)psRealloc(old->data.V, numRows * sizeof(psPtr ));
+
+    // recreate the row pointers
+    old->data.V[0] = old->rawDataBuffer;
+    for (psS32 i = 1; i < numRows; i++) {
+        old->data.V[i] = (psPtr )((int8_t *) old->data.V[i - 1] + rowSize);
+    }
+
+    *(psU32 *)&old->numCols = numCols;
+    *(psU32 *)&old->numRows = numRows;
+    *(psElemType* ) & old->type.type = type;
+
+    return old;
+}
+
+psImage* psImageCopy(psImage* restrict output,
+                     const psImage* input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    psS32 elementSize;
+    psS32 elements;
+    psS32 numRows;
+    psS32 numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input == output) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psError(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) {
+        psError(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 (psS32 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(psS32 row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (psS32 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);
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                    typeStr);
+            psFree(output);
+
+            break;
+        }
+    }
+    return output;
+}
+
+psS32 psImageFreeChildren(psImage* image)
+{
+    psS32 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 (psS32 i=0;i<numFreed;i++) {
+            children[i]->parent = NULL;
+        }
+
+        psFree(image->children);
+        image->children = NULL;
+    }
+
+    return numFreed;
+}
+
+/*****************************************************************************
+XXX: update function description.
+ 
+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,
+                              psU32 maskVal,
+                              psC64 unexposedValue,
+                              psImageInterpolateMode mode)
+{
+
+    if (input == NULL) {
+        psError(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:                                                         \
+        psError(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);
+            psError(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, \
+        psU32 maskVal, \
+        psF64 unexposedValue) \
+{ \
+    psS32 intX = (psS32) round((psF64)(x) - 0.5 + FLT_EPSILON); \
+    psS32 intY = (psS32) round((psF64)(y) - 0.5 + FLT_EPSILON); \
+    psS32 lastX = input->numCols - 1; \
+    psS32 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, \
+        psU32 maskVal, \
+        psC64 unexposedValue) \
+{ \
+    psS32 intX = (psS32) round((psF64)(x) - 0.5); \
+    psS32 intY = (psS32) round((psF64)(y) - 0.5); \
+    psS32 lastX = input->numCols - 1; \
+    psS32 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, \
+        psU32 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; \
+    psS32 intFloorX = (psS32) floorX; \
+    psS32 intFloorY = (psS32) floorY; \
+    psS32 lastX = input->numCols - 1; \
+    psS32 lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    psBool valid00 = false; \
+    psBool valid01 = false; \
+    psBool valid10 = false; \
+    psBool 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; \
+    psBool 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; \
+    psBool 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, \
+        psU32 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; \
+    psS32 intFloorX = (psS32) floorX; \
+    psS32 intFloorY = (psS32) floorY; \
+    psS32 lastX = input->numCols - 1; \
+    psS32 lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    psBool valid00 = false; \
+    psBool valid01 = false; \
+    psBool valid10 = false; \
+    psBool 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; \
+    psBool 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; \
+    psBool 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/rel4/psLib/src/mathtypes/psImage.h
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psImage.h	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psImage.h	(revision 3057)
@@ -0,0 +1,239 @@
+/** @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.45 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 03:26:23 $
+ *
+ *  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 psU32 numCols;        ///< Number of columns in image
+    const psU32 numRows;        ///< Number of rows in image.
+    const psS32 col0;                    ///< Column position relative to parent.
+    const psS32 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.
+
+    psPtr rawDataBuffer;
+}
+psImage;
+
+/** Basic image region structure.
+ *
+ * Struct for specifying a rectangular area in an image.
+ *
+ */
+typedef struct
+{
+    psF32 x0;                         ///< the first column of the region.
+    psF32 x1;                         ///< the last column of the region.
+    psF32 y0;                         ///< the first row of the region.
+    psF32 y1;                         ///< the last row of the region.
+}
+psRegion;
+
+/** 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(
+    psU32 numCols,                     ///< Number of rows in image.
+    psU32 numRows,                     ///< Number of columns in image.
+    const psElemType type              ///< Type of data for image.
+);
+
+/** Create a psRegion with the specified attributes.
+ *
+ * Uses psLib memory allocation functions to create a psRegion the
+ * specified x0, x1, y0, and y1.
+ *
+ * @return psRegion* : Pointer to psRegion.
+ *
+ */
+psRegion* psRegionAlloc(
+    psF32 x0,                         ///< the first column of the region.
+    psF32 x1,                         ///< the last column of the region.
+    psF32 y0,                         ///< the first row of the region.
+    psF32 y1                          ///< the last row of the region.
+);
+
+/** Create a psRegion with the attribute values given as a string.
+ *
+ *  Create a psRegion with the attribute values given as a string.  The format
+ *  shall be of the standard IRAF form '[x0:x1,y0:y1]'
+ *
+ *  @return psRegion*:  A new psRegion struct, or NULL is not successful.
+ */
+psRegion* psRegionFromString(
+    char* region                       ///< image rectangular region in the form '[x0:x1,y0:y1]'
+);
+
+/** Create a string of the standard IRAF form '[x0:x1,y0:y1]' from a psRegion.
+ *
+ *  @return char*:  A new string representing the psRegion as text, or NULL
+ *                  is not successful.
+ */
+char* psRegionToString(
+    psRegion* region                   ///< the psRegion to convert to a string
+);
+
+/** 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
+    psU32 numCols,                     ///< the desired number of columns in image
+    psU32 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 psS32      Number of children freed.
+ *
+ */
+psS32 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
+    psU32 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 */ \
+        psU32 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 */ \
+        psU32 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 */ \
+        psU32 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 */ \
+        psU32 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/rel4/psLib/src/mathtypes/psScalar.c
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psScalar.c	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psScalar.c	(revision 3057)
@@ -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.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-08 02:03:49 $
+ *
+ *  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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                dataType);
+        psFree(scalar);
+        return NULL;
+    }
+
+    return scalar;
+}
+
+psScalar* psScalarCopy(psScalar *scalar)
+{
+    psElemType dataType;
+    psScalar *newScalar = NULL;
+
+    if (scalar == NULL) {
+        psError(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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                dataType);
+        return NULL;
+    }
+
+    return newScalar;
+}
Index: /branches/rel4/psLib/src/mathtypes/psScalar.h
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psScalar.h	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psScalar.h	(revision 3057)
@@ -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/rel4/psLib/src/mathtypes/psVector.c
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psVector.c	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psVector.c	(revision 3057)
@@ -0,0 +1,408 @@
+
+/** @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.32 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-09 21:30:43 $
+*
+*  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(psU32 nalloc, psElemType elemType)
+{
+    psVector* psVec = NULL;
+    psS32 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, psU32 nalloc)
+{
+    psS32 elementSize = 0;
+    psElemType elemType;
+
+    if (in == NULL) {
+        psError(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, psU32 n, psElemType type)
+{
+    psS32 byteSize;
+
+    if (in == NULL) {
+        return psVectorAlloc(n, type);
+    }
+
+    if (in->type.dimen !=  PS_DIMEN_VECTOR &&
+            in->type.dimen !=  PS_DIMEN_TRANSV) {
+        psFree(in);
+        psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    psS32 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 (psS32 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); \
+                psError(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);
+            psError(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)
+{
+    psS32 N = 0;
+    psS32 elSize = 0;
+    psPtr inVec = NULL;
+    psPtr outVec = NULL;
+    psElemType inType = 0;
+
+    if (inVector == NULL) {
+        psError(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:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                inType);
+    }
+
+    return outVector;
+}
+
+psVector* psVectorSortIndex(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    psS32 N = 0;
+    psVector* tmpVector = NULL;
+    psVector* checkVector = NULL;
+    psElemType inType = 0;
+    psU32* outVec;
+
+    if (inVector == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    inType = inVector->type.type;
+    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);
+
+    checkVector = psVectorAlloc(N,PS_TYPE_U8);
+    for(psS32 k=0; k<N; k++) {
+        checkVector->data.U8[k] = 0;
+    }
+
+    #define SORT_INDICES(TYPE,absfcn,maxError) {                              \
+        ps##TYPE* inVec = inVector->data.TYPE;                                \
+        ps##TYPE* tmpVec = tmpVector->data.TYPE;                              \
+        ps##TYPE  diff;                                                       \
+        for(psS32 i=0; i<N; i++) {                                              \
+            for(psS32 j=0; j<N; j++) {                                          \
+                if(checkVector->data.U8[j] == 0 ) {                                    \
+                    diff = absfcn(tmpVec[i] - inVec[j]);                          \
+                    if(diff < maxError) {                                         \
+                        outVec[i] = j;                                            \
+                        checkVector->data.U8[j] = 1; \
+                        break;                                                    \
+                    }                                                             \
+                } \
+            }                                                                 \
+        }                                                                     \
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        SORT_INDICES(U8,abs,1);
+        break;
+    case PS_TYPE_U16:
+        SORT_INDICES(U16,abs,1);
+        break;
+    case PS_TYPE_U32:
+        SORT_INDICES(U32,abs,1);
+        break;
+    case PS_TYPE_U64:
+        SORT_INDICES(U64,abs,1);
+        break;
+    case PS_TYPE_S8:
+        SORT_INDICES(S8,abs,1);
+        break;
+    case PS_TYPE_S16:
+        SORT_INDICES(S16,abs,1);
+        break;
+    case PS_TYPE_S32:
+        SORT_INDICES(S32,abs,1);
+        break;
+    case PS_TYPE_S64:
+        SORT_INDICES(S64,abs,1);
+        break;
+    case PS_TYPE_F32:
+        SORT_INDICES(F32,fabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_F64:
+        SORT_INDICES(F64,fabs,DBL_EPSILON);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                inType);
+    }
+
+    // Free temp memory
+    psFree(tmpVector);
+    psFree(checkVector);
+
+    return outVector;
+}
Index: /branches/rel4/psLib/src/mathtypes/psVector.h
===================================================================
--- /branches/rel4/psLib/src/mathtypes/psVector.h	(revision 3057)
+++ /branches/rel4/psLib/src/mathtypes/psVector.h	(revision 3057)
@@ -0,0 +1,148 @@
+/** @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.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
+ *
+ *  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.
+    psU32 nalloc;        ///< Total number of elements available.
+    psU32 n;             ///< Number of elements in use.
+
+    union {
+        psBool B;               ///< Boolean data.
+        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(
+    psU32 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.
+    psU32 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.
+
+    psU32 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/rel4/psLib/src/parseErrorCodes.pl
===================================================================
--- /branches/rel4/psLib/src/parseErrorCodes.pl	(revision 3057)
+++ /branches/rel4/psLib/src/parseErrorCodes.pl	(revision 3057)
@@ -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/rel4/psLib/src/psErrorCodes.dat
===================================================================
--- /branches/rel4/psLib/src/psErrorCodes.dat	(revision 3057)
+++ /branches/rel4/psLib/src/psErrorCodes.dat	(revision 3057)
@@ -0,0 +1,19 @@
+#
+#  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
+OS_CALL_FAILED                 unexpected result from an OS standard library call.
Index: /branches/rel4/psLib/src/pslib.h
===================================================================
--- /branches/rel4/psLib/src/pslib.h	(revision 3057)
+++ /branches/rel4/psLib/src/pslib.h	(revision 3057)
@@ -0,0 +1,182 @@
+
+/** @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.29 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-12 22:17:01 $
+*
+*  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"
+
+/// @defgroup Configure Configure psLib
+/// @ingroup SysUtils
+#include "psConfigure.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"
+
+/// @}
+
+// FileUtils
+/// @defgroup FileUtils File Utilities
+/// @{
+#include "psFits.h"
+
+/// @defgroup LookupTable Lookup Table
+/// @ingroup FileUtils
+#include "psLookupTable.h"
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/sys/psAbort.c
===================================================================
--- /branches/rel4/psLib/src/sys/psAbort.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psAbort.c	(revision 3057)
@@ -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/rel4/psLib/src/sys/psAbort.h
===================================================================
--- /branches/rel4/psLib/src/sys/psAbort.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psAbort.h	(revision 3057)
@@ -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/rel4/psLib/src/sys/psConfigure.c
===================================================================
--- /branches/rel4/psLib/src/sys/psConfigure.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psConfigure.c	(revision 3057)
@@ -0,0 +1,57 @@
+/** @file  psConfigure.c
+ *
+ *  @brief Contains the declarations for initialization, memory finalization, and configuration.
+ *
+ *  These functions initalize psLib data before the beginning of a run and remove (finalize) the
+ *  same data after the run is complete. A function is also provided to return the current
+ *  psLib version.
+ *
+ *  @ingroup Configure
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-03 23:35:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include "psString.h"
+#include "psTime.h"
+#include "psError.h"
+#include "psConfigure.h"
+#include "psSysUtilsErrors.h"
+
+
+#ifndef PS_LIB_VERSION
+#define PS_LIB_VERSION "psLib version unknown"
+#pragma warning PS_LIB_VERSION was not defined in the makefile.
+#endif
+
+char* psLibVersion(void)
+{
+    // PS_LIB_VERSION comes from Makefile.Globals
+    return(psStringCopy(PS_LIB_VERSION));
+}
+
+void psLibInit(bool predictable, const char* timeConfig)
+{
+    // Still needs error codes to be set
+    // Still needs random number generator initialization
+    // Please code me, Robert and George.
+
+    if(!p_psTimeInit(timeConfig)) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED, "psTime");
+        return;
+    }
+}
+
+void psLibFinalize(void)
+{
+    // Users of persistent memory should free them in this function
+
+    if(!p_psTimeFinalize()) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED, "psTime");
+        return;
+    }
+}
Index: /branches/rel4/psLib/src/sys/psConfigure.h
===================================================================
--- /branches/rel4/psLib/src/sys/psConfigure.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psConfigure.h	(revision 3057)
@@ -0,0 +1,66 @@
+/** @file  psConfigure.h
+ *
+ *  @brief Contains the declarations for initialization, memory finalization, and configuration.
+ *
+ *  These functions initalize psLib data before the beginning of a run and remove (finalize) the
+ *  same data after the run is complete. A function is also provided to return the current
+ *  psLib version.
+ *
+ *  @ingroup Configure
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author George Gusciora, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-10 20:58:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_CONFIGURE_H
+#define PS_CONFIGURE_H
+
+
+/** @addtogroup Configure
+ *  @{
+ */
+
+/** Get current psLib version
+ *
+ *  Returns the current psLib version name as a string.
+ *
+ *  @return char*: String with version name.
+ */
+char* psLibVersion(
+    void
+);
+
+/** Initializes persistent memory.
+ *
+ *  Creates persistant memory items used throughout psLib. Items created within this method should be freed
+ *  with the psLibFinalize function.
+ *  current, a non-NULL psErr is returned with code PS_ERR_NONE.
+ *
+ *  @return void: void.
+ */
+void psLibInit(
+    bool predictable,
+    const char* timeConfig
+);
+
+/** Removes persistant memory created with the psLibInit function.
+ *
+ *  The memory created but not freed by psLib modules should be freed within this
+ *  function at the end of a psLib execution cycle.
+ *
+ *  @return void: void.
+ */
+void psLibFinalize(
+    void
+);
+
+
+/* @} */
+
+#endif
Index: /branches/rel4/psLib/src/sys/psError.c
===================================================================
--- /branches/rel4/psLib/src/sys/psError.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psError.c	(revision 3057)
@@ -0,0 +1,193 @@
+/** @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.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 19:50:45 $
+ *
+ *  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 psU32 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;
+}
+
+psErrorCode p_psError(const char* file,
+                      int lineno,
+                      const char* func,
+                      psErrorCode code,
+                      psBool new,
+                      const char* fmt,
+                      ...)
+{
+    char errMsg[2048];
+    psErr* err;
+    char msgName[256];
+
+    snprintf(msgName,256,"%s (%s:%d)",func,file,lineno);
+
+    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,2048,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(psS32 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;
+}
+
+psS32 psErrorGetStackSize()
+{
+    return errorStackSize;
+}
+
+psErr* psErrorLast(void)
+{
+    return psErrorGet(0);
+}
+
+void psErrorClear(void)
+{
+    pthread_mutex_lock(&lockErrorStack);
+
+    for (int lcv=0;lcv < errorStackSize; lcv++) {
+        p_psMemSetPersistent(errorStack[lcv],false);
+        p_psMemSetPersistent(errorStack[lcv]->msg,false);
+        p_psMemSetPersistent(errorStack[lcv]->name,false);
+        psFree(errorStack[lcv]);
+    }
+    errorStackSize = 0;
+
+    pthread_mutex_unlock(&lockErrorStack);
+
+}
+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 (psS32 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/rel4/psLib/src/sys/psError.h
===================================================================
--- /branches/rel4/psLib/src/sys/psError.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psError.h	(revision 3057)
@@ -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.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 19:50:45 $
+ *
+ *  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(
+    psS32 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);
+
+/** Get the error stack depth
+ *
+ *  @return psS32   The number of items on the error stack
+ */
+psS32 psErrorGetStackSize();
+
+/** 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.
+ *
+ *  This function modifies the error stack.
+ *
+ *  @return psErrorCode    the given error code
+ */
+psErrorCode p_psError(
+    const char* file,
+    int lineno,
+    const char* func,
+    psErrorCode code,                  ///< Error class code
+    psBool new,                        ///< true if error originates at this location
+    const char* fmt,
+    ...
+);
+
+#define psError(code,new,...) p_psError(__FILE__,__LINE__,__func__,code,new,__VA_ARGS__)
+
+/** 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/rel4/psLib/src/sys/psErrorCodes.c
===================================================================
--- /branches/rel4/psLib/src/sys/psErrorCodes.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psErrorCodes.c	(revision 3057)
@@ -0,0 +1,188 @@
+/** @file  psErrorCodes.c
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-13 20:49:56 $
+ *
+ *  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 found"},
+            {PS_ERR_OS_CALL_FAILED,"unexpected result from an OS standard library call"},
+            //~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
+
+    psS32 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.
+        psListIterator* iter = psListIteratorAlloc(dynamicErrorCodes,PS_LIST_HEAD);
+        while ((desc = (psErrorDescription*)psListGetNext(iter)) != NULL) {
+            if (desc->code == code) {
+                psFree(iter);
+                return desc;
+            }
+        }
+        psFree(iter);
+    }
+    return NULL;
+}
+
+static void freeErrorDescription(psErrorDescription* err)
+{
+    psFree((psPtr)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,
+                     psS32 nerror)
+{
+    if (nerror < 1) {
+        return;
+    }
+
+    if (errors == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION);
+        return;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        dynamicErrorCodes = psListAlloc(NULL);
+        p_psMemSetPersistent(dynamicErrorCodes,true);
+
+        p_psMemSetPersistent(dynamicErrorCodes->iterators,true);
+        p_psMemSetPersistent(dynamicErrorCodes->iterators->data,true);
+        for (int i = 0; i < dynamicErrorCodes->iterators->n;i++) {
+            p_psMemSetPersistent(dynamicErrorCodes->iterators->data[i],true);
+        }
+    }
+
+    for (psS32 i=0;i<nerror;i++) {
+        psErrorDescription* err = psErrorDescriptionAlloc(
+                                      errors[i].code, errors[i].description);
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent((psPtr)err->description,true);
+        if (! psListAdd(dynamicErrorCodes,
+                        PS_LIST_HEAD,
+                        err) ) {
+
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED,
+                    i);
+        }
+        p_psMemSetPersistent(dynamicErrorCodes->head,true);
+        psFree(err);
+    }
+}
+
+psBool 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 psListRemoveData(dynamicErrorCodes,(psPtr)desc);
+}
Index: /branches/rel4/psLib/src/sys/psErrorCodes.h
===================================================================
--- /branches/rel4/psLib/src/sys/psErrorCodes.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psErrorCodes.h	(revision 3057)
@@ -0,0 +1,111 @@
+/** @file  psErrorCodes.h
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_CODES_H
+#define PS_ERROR_CODES_H
+
+#include "psType.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 found
+    PS_ERR_OS_CALL_FAILED,   ///< unexpected result from an OS standard library call
+    //~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
+    psS32 nerror                         ///< number of errors in input array
+);
+
+/** Clears error codes registered via psErrorRegister.
+ *
+ *  @return psBool    TRUE if given errorcode was removed, otherwise FALSE.
+ */
+psBool p_psErrorUnregister(
+    psErrorCode code                   ///< the error code to find and remove
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/sys/psLogMsg.c
===================================================================
--- /branches/rel4/psLib/src/sys/psLogMsg.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psLogMsg.c	(revision 3057)
@@ -0,0 +1,391 @@
+/** @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.35 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static psS32 p_psGlobalLogDest;
+    static psS32 p_psGlobalLogLevel;
+    static psS32 p_psLogTime;
+    static psS32 p_psLogHost;
+    static psS32 p_psLogLevel;
+    static psS32 p_psLogName;
+    static psS32 p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.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 psS32 globalLogLevel = PS_LOG_INFO;        // log all messages at this or above
+static psBool logTime = true;     // Flag to include time info
+static psBool logHost = true;     // Flag to include host info
+static psBool logLevel = true;    // Flag to include level info
+static psBool logName = true;     // Flag to include name info
+static psBool logMsg = true;      // Flag to include message info
+
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (psS32): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+psS32 psLogSetLevel(psS32 level)
+{
+    // Save old global log level for changing it.
+    psS32 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 (psS32): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+psBool 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) {
+        psError(PS_ERR_LOCATION_INVALID, true,
+                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;
+        }
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID,
+                location);
+        return 1;
+    } else if (strcmp(protocol, "file") == 0) {
+        FILE *file = fopen(location, "w");
+
+        if (file == NULL) {
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED,
+                    location);
+            return false;
+        }
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = file;
+        return true;
+    }
+
+    psError(PS_ERR_LOCATION_INVALID, true,
+            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:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    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, psS32 level, const char *fmt, va_list ap)
+{
+    static psS32 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
+    psS32 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, psS32 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/rel4/psLib/src/sys/psLogMsg.h
===================================================================
--- /branches/rel4/psLib/src/sys/psLogMsg.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psLogMsg.h	(revision 3057)
@@ -0,0 +1,117 @@
+/** @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.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  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 "psType.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 psS32     true if set successfully, otherwise false.
+ */
+psBool 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 psS32    old logging level
+ */
+psS32 psLogSetLevel(
+    psS32 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
+    psS32 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
+    psS32 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/rel4/psLib/src/sys/psMemory.c
===================================================================
--- /branches/rel4/psLib/src/sys/psMemory.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psMemory.c	(revision 3057)
@@ -0,0 +1,697 @@
+/** @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.47 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-13 20:49:56 $
+*
+*  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 <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+#define P_PS_MEMMAGIC (psPtr )0xdeadbeef   // Magic number in psMemBlock header
+
+#define P_PS_LARGE_BLOCK_SIZE 65536        // size where under, we try to recycle
+
+static psS32 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 psS32 recycleBins = 13;
+static psS32 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 psPtr memExhaustedCallbackDefault(size_t size)
+{
+    psPtr ptr = NULL;
+
+    pthread_mutex_lock(&recycleMemBlockListMutex);
+    psS32 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, psS32 lineno)
+{
+    if (ptr->refCounter < 1) {
+        psError(PS_ERR_MEMORY_CORRUPTION, false,
+                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 psS32 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) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_NULL_BLOCK);
+        return 1;
+    }
+
+    if (m->refCounter == 0) {
+        // using an unreferenced block of memory, are you?
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE,
+                m->id);
+        return 1;
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_UNDERFLOW,
+                m->id);
+        return 1;
+    }
+    if (*(psPtr *)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_OVERFLOW,
+                m->id);
+        return 1;
+    }
+
+    return 0;
+}
+
+psS32 psMemCheckCorruption(psBool abort_on_error)
+{
+    psS32 nbad = 0;               // number of bad blocks
+    psBool 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;
+}
+
+psPtr p_psAlloc(size_t size, const char *file, psS32 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.
+        psS32 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(psPtr ));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if (ptr == NULL) {
+                psAbort(__func__, "Failed to allocate %u bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        *(psPtr*)&ptr->startblock = P_PS_MEMMAGIC;
+        *(psPtr*)&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;
+    *(psU32 *)&ptr->lineno = lineno;
+    *(psPtr *)((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
+}
+
+psPtr p_psRealloc(psPtr vptr, size_t size, const char *file, psS32 lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+        psBool isBlockLast = false;
+
+        if (checkMemBlock(ptr, __func__) != 0) {
+            memProblemCallback(ptr, file, lineno);
+            psAbort(file, "Realloc detected a memory corruption (id %lld @ %s:%d).",
+                    ptr->id, ptr->file, ptr->lineno);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock* ) realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr ));
+
+        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;
+        *(psPtr *)((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(psPtr vptr, const char *file, psS32 lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+    if (ptr->refCounter < 1) {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+        psAbort(__func__,PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno);
+        psAbort(__func__,"Memory Corruption Detected.");
+    }
+
+    (void)p_psMemDecrRefCounter(vptr, file, lineno);    // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks.
+ */
+psS32 psMemCheckLeaks(psMemoryId id0, psMemBlock* ** arr, FILE * fd, psBool persistence)
+{
+    psS32 nleak = 0;
+    psS32 j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                ( (persistence) || (!persistence && !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, (int)iter->lineno, (long)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) &&
+                ( (persistence) || (!persistence && !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(psPtr vptr)
+{
+    psMemBlock* ptr;
+    psU32 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
+psPtr p_psMemIncrRefCounter(psPtr vptr, const char *file, psS32 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
+psPtr p_psMemDecrRefCounter(psPtr vptr, const char *file, psS32 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) {
+
+            psS32 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(psPtr 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(psPtr vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->freeFcn;
+}
+
+psBool p_psMemGetPersistent(psPtr 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(psPtr vptr,psBool value)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->persistent = value;
+}
Index: /branches/rel4/psLib/src/sys/psMemory.h
===================================================================
--- /branches/rel4/psLib/src/sys/psMemory.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psMemory.h	(revision 3057)
@@ -0,0 +1,447 @@
+/** @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.32 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-22 20:49:59 $
+ *
+ *  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 <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psType.h"
+
+/** @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 psU64 psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef psU64 psReferenceCount;
+
+/// typedef for deallocator.
+typedef void (*psFreeFcn) (psPtr 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 psPtr 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 psS32 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
+    psBool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
+    const psPtr 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
+    psS32 lineno                         ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return psPtr pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psPtr (*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 psPtr pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree 
+ */
+#ifdef DOXYGEN
+psPtr psAlloc(size_t size       ///< Size required
+             );
+#else
+
+psPtr p_psAlloc(size_t size,    ///< Size required
+                const char *file,       ///< File of call
+                psS32 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(
+    psPtr 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(
+    psPtr 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(
+    psPtr ptr,                         ///< the memory block to operate on
+    psBool 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 psBool    true if memory is marked persistent, otherwise false.
+ */
+psBool p_psMemGetPersistent(
+    psPtr ptr                          ///< the memory block to check.
+);
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return psPtr pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+psPtr psRealloc(
+    psPtr ptr                          ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+);
+#else
+
+psPtr p_psRealloc(
+    psPtr ptr,                         ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+    const char *file,                  ///< File of call
+    psS32 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(
+    psPtr ptr,                         ///< Pointer to free, if NULL, function returns immediately.
+);
+#else
+
+void p_psFree(
+    psPtr ptr,                        ///< Pointer to free
+    const char *file,                 ///< File of call
+    psS32 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 psS32  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
+ */
+psS32 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)
+    psBool persistence                 ///< make check across all object even persistent ones
+);
+
+/** 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
+ */
+psS32 psMemCheckCorruption(
+    psBool abort_on_error                ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    psPtr vptr                         ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+#ifdef DOXYGEN
+psPtr psMemIncrRefCounter(
+    psPtr vptr                         ///< Pointer to increment refCounter, and return
+);
+#else
+
+psPtr p_psMemIncrRefCounter(
+    psPtr vptr,                        ///< Pointer to increment refCounter, and return
+    const char *file,                  ///< File of call
+    psS32 lineno                         ///< Line number of call
+);
+
+#define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ *
+ *  @return psPtr    the pointer deremented in refCount, or NULL if pointer is 
+ *                   fully dereferenced.
+ */
+#ifdef DOXYGEN
+psPtr psMemDecrRefCounter(
+    psPtr vptr                         ///< Pointer to decrement refCounter, and return
+);
+#else
+
+psPtr p_psMemDecrRefCounter(
+    psPtr vptr,                        ///< Pointer to decrement refCounter, and return
+    const char *file,                  ///< File of call
+    psS32 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/rel4/psLib/src/sys/psString.c
===================================================================
--- /branches/rel4/psLib/src/sys/psString.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psString.c	(revision 3057)
@@ -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.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  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, psS32 nChar)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if (nChar < 0) {
+        // Log error message and return NULL
+        psError(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/rel4/psLib/src/sys/psString.h
===================================================================
--- /branches/rel4/psLib/src/sys/psString.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psString.h	(revision 3057)
@@ -0,0 +1,71 @@
+/** @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.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+#include "psType.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 */
+
+    psS32 nChar
+    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel4/psLib/src/sys/psTrace.c
===================================================================
--- /branches/rel4/psLib/src/sys/psTrace.c	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psTrace.c	(revision 3057)
@@ -0,0 +1,531 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.40 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-02 21:12:52 $
+ *
+ *  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 psS64 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, psS32 level);
+
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+static p_psComponent* componentAlloc(const char *name, psS32 level)
+{
+    p_psComponent* comp = psAlloc(sizeof(p_psComponent));
+
+    p_psMemSetPersistent(comp,true);
+    p_psMemSetDeallocator(comp, (psFreeFcn) componentFree);
+    comp->name = psStringCopy(name);
+    p_psMemSetPersistent((psPtr)comp->name,true);
+    comp->level = level;
+    comp->n = 0;
+    comp->p_psSpecified = false;
+    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 (psS32 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((psPtr)comp->name,false);
+    psFree((psPtr)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)
+{
+    psS32 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 psBool componentAdd(const char *addNodeName, psS32 level)
+{
+    psS32 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;
+    psS32 nodeExists = 0;
+
+    // XXX: Verify that this is the correct behavior.
+    if (strcmp("", addNodeName) == 0) {
+        psError(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] != '.') {
+        psError(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
+*****************************************************************************/
+psBool psTraceSetLevel(const char *comp,   // component of interest
+                       psS32 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) ) {
+        psError(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 psS32 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;
+    psS32 i = 0;
+    psS32 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.
+ *****************************************************************************/
+psS32 psTraceGetLevel(const char *name)
+{
+    char *compName = NULL;
+    psS32 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);
+    }
+
+    // XXX: The default trace level is currently set at -1, which is not a
+    // valid trace level.  This is convenient in determining whether or not
+    // a component should inherit the trace level from parent nodes.  However,
+    // it's not clear that -1 should ever be returned by this function.
+    // The SDR is unclear on this point and we should probably request IfA
+    // comment.
+    if (traceLevel == PS_DEFAULT_TRACE_LEVEL) {
+        traceLevel = PS_THE_OTHER_DEFAULT_TRACE_LEVEL;
+    }
+
+    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,
+                               psS32 depth,
+                               psS32 defLevel)
+{
+    psS32 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_THE_OTHER_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
+               psS32 level,       // desired trace level
+               ...)             // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    psS32 i = 0;
+
+    if (NULL == comp) {
+        psError(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/rel4/psLib/src/sys/psTrace.h
===================================================================
--- /branches/rel4/psLib/src/sys/psTrace.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psTrace.h	(revision 3057)
@@ -0,0 +1,94 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-24 20:12:28 $
+ *
+ *  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
+#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL 0
+
+/** \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
+        psS32 level;                  // trace level for this component
+        bool p_psSpecified;
+        psS32 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
+               psS32 myLevel,     ///< desired trace level
+               ...)             ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+psBool psTraceSetLevel(const char *facil,     ///< facilty of interest
+                       psS32 level)     ///< desired trace level
+;
+
+/// Get the trace level
+psS32 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/rel4/psLib/src/sys/psType.h
===================================================================
--- /branches/rel4/psLib/src/sys/psType.h	(revision 3057)
+++ /branches/rel4/psLib/src/sys/psType.h	(revision 3057)
@@ -0,0 +1,236 @@
+
+/** @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.27 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:21 $
+*
+*  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>
+#include <stdbool.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 bool psBool;                   ///< boolean value
+
+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 psS16 integer.
+    PS_TYPE_U32  = 0x0304,             ///< Unsigned integer.
+    PS_TYPE_U64  = 0x0308,             ///< Unsigned psS64 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_BOOL = 0x1301,             ///< Boolean.
+    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
+typedef psBool psBOOL;                 ///< allow psBOOL to be used instead of psBool (for macros)
+
+#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_BOOL_NAME "psBool"
+#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_BOOL: \
+    value = PS_TYPE_BOOL_NAME; \
+    break; \
+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 if the psElemType is boolean type.
+#define PS_IS_PSELEMTYPE_BOOL(x) ((x & 0x1000) == 0x1000)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(psPtr) :(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;
+
+/** The type of a basic data type
+ *
+ *  All psLib complex types consist of primitive components.  This structure provides the ability to cast
+ *  an unknown data structure to safely test the underlining data type.
+ *
+ */
+typedef struct
+{
+    psType  type;              ///< Data type information
+}
+psMath;
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/sysUtils/.cvsignore
===================================================================
--- /branches/rel4/psLib/src/sysUtils/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/.cvsignore	(revision 3057)
@@ -0,0 +1,2 @@
+*.i
+psErrorCodes.h
Index: /branches/rel4/psLib/src/sysUtils/Makefile
===================================================================
--- /branches/rel4/psLib/src/sysUtils/Makefile	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/Makefile	(revision 3057)
@@ -0,0 +1,96 @@
+###############################################################################
+##
+##  Makefile:   sysUtils
+##
+##  $Revision: 1.24 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-03 23:41:36 $
+##
+##  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) -DPS_LIB_VERSION="\"$(PS_LIB_VERSION)\"" -I../collections -I../dataManip -I../sysUtils -I../include -I../astronomy -I../image -I..
+
+# Define the source objects
+
+SRC_OBJS = psMemory.o     \
+           psError.o      \
+           psTrace.o      \
+           psLogMsg.o     \
+           psAbort.o      \
+           psString.o     \
+	   psConfigure.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/rel4/psLib/src/sysUtils/README
===================================================================
--- /branches/rel4/psLib/src/sysUtils/README	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/README	(revision 3057)
@@ -0,0 +1,2 @@
+This directory includes code related to the 'system utilities' section of the
+IfA supplied SDR.
Index: /branches/rel4/psLib/src/sysUtils/psAbort.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psAbort.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psAbort.c	(revision 3057)
@@ -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/rel4/psLib/src/sysUtils/psAbort.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psAbort.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psAbort.h	(revision 3057)
@@ -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/rel4/psLib/src/sysUtils/psConfigure.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psConfigure.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psConfigure.c	(revision 3057)
@@ -0,0 +1,57 @@
+/** @file  psConfigure.c
+ *
+ *  @brief Contains the declarations for initialization, memory finalization, and configuration.
+ *
+ *  These functions initalize psLib data before the beginning of a run and remove (finalize) the
+ *  same data after the run is complete. A function is also provided to return the current
+ *  psLib version.
+ *
+ *  @ingroup Configure
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-03 23:35:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include "psString.h"
+#include "psTime.h"
+#include "psError.h"
+#include "psConfigure.h"
+#include "psSysUtilsErrors.h"
+
+
+#ifndef PS_LIB_VERSION
+#define PS_LIB_VERSION "psLib version unknown"
+#pragma warning PS_LIB_VERSION was not defined in the makefile.
+#endif
+
+char* psLibVersion(void)
+{
+    // PS_LIB_VERSION comes from Makefile.Globals
+    return(psStringCopy(PS_LIB_VERSION));
+}
+
+void psLibInit(bool predictable, const char* timeConfig)
+{
+    // Still needs error codes to be set
+    // Still needs random number generator initialization
+    // Please code me, Robert and George.
+
+    if(!p_psTimeInit(timeConfig)) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED, "psTime");
+        return;
+    }
+}
+
+void psLibFinalize(void)
+{
+    // Users of persistent memory should free them in this function
+
+    if(!p_psTimeFinalize()) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED, "psTime");
+        return;
+    }
+}
Index: /branches/rel4/psLib/src/sysUtils/psConfigure.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psConfigure.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psConfigure.h	(revision 3057)
@@ -0,0 +1,66 @@
+/** @file  psConfigure.h
+ *
+ *  @brief Contains the declarations for initialization, memory finalization, and configuration.
+ *
+ *  These functions initalize psLib data before the beginning of a run and remove (finalize) the
+ *  same data after the run is complete. A function is also provided to return the current
+ *  psLib version.
+ *
+ *  @ingroup Configure
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author George Gusciora, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-10 20:58:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_CONFIGURE_H
+#define PS_CONFIGURE_H
+
+
+/** @addtogroup Configure
+ *  @{
+ */
+
+/** Get current psLib version
+ *
+ *  Returns the current psLib version name as a string.
+ *
+ *  @return char*: String with version name.
+ */
+char* psLibVersion(
+    void
+);
+
+/** Initializes persistent memory.
+ *
+ *  Creates persistant memory items used throughout psLib. Items created within this method should be freed
+ *  with the psLibFinalize function.
+ *  current, a non-NULL psErr is returned with code PS_ERR_NONE.
+ *
+ *  @return void: void.
+ */
+void psLibInit(
+    bool predictable,
+    const char* timeConfig
+);
+
+/** Removes persistant memory created with the psLibInit function.
+ *
+ *  The memory created but not freed by psLib modules should be freed within this
+ *  function at the end of a psLib execution cycle.
+ *
+ *  @return void: void.
+ */
+void psLibFinalize(
+    void
+);
+
+
+/* @} */
+
+#endif
Index: /branches/rel4/psLib/src/sysUtils/psError.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psError.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psError.c	(revision 3057)
@@ -0,0 +1,193 @@
+/** @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.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 19:50:45 $
+ *
+ *  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 psU32 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;
+}
+
+psErrorCode p_psError(const char* file,
+                      int lineno,
+                      const char* func,
+                      psErrorCode code,
+                      psBool new,
+                      const char* fmt,
+                      ...)
+{
+    char errMsg[2048];
+    psErr* err;
+    char msgName[256];
+
+    snprintf(msgName,256,"%s (%s:%d)",func,file,lineno);
+
+    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,2048,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(psS32 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;
+}
+
+psS32 psErrorGetStackSize()
+{
+    return errorStackSize;
+}
+
+psErr* psErrorLast(void)
+{
+    return psErrorGet(0);
+}
+
+void psErrorClear(void)
+{
+    pthread_mutex_lock(&lockErrorStack);
+
+    for (int lcv=0;lcv < errorStackSize; lcv++) {
+        p_psMemSetPersistent(errorStack[lcv],false);
+        p_psMemSetPersistent(errorStack[lcv]->msg,false);
+        p_psMemSetPersistent(errorStack[lcv]->name,false);
+        psFree(errorStack[lcv]);
+    }
+    errorStackSize = 0;
+
+    pthread_mutex_unlock(&lockErrorStack);
+
+}
+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 (psS32 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/rel4/psLib/src/sysUtils/psError.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psError.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psError.h	(revision 3057)
@@ -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.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 19:50:45 $
+ *
+ *  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(
+    psS32 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);
+
+/** Get the error stack depth
+ *
+ *  @return psS32   The number of items on the error stack
+ */
+psS32 psErrorGetStackSize();
+
+/** 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.
+ *
+ *  This function modifies the error stack.
+ *
+ *  @return psErrorCode    the given error code
+ */
+psErrorCode p_psError(
+    const char* file,
+    int lineno,
+    const char* func,
+    psErrorCode code,                  ///< Error class code
+    psBool new,                        ///< true if error originates at this location
+    const char* fmt,
+    ...
+);
+
+#define psError(code,new,...) p_psError(__FILE__,__LINE__,__func__,code,new,__VA_ARGS__)
+
+/** 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/rel4/psLib/src/sysUtils/psErrorCodes.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psErrorCodes.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psErrorCodes.c	(revision 3057)
@@ -0,0 +1,188 @@
+/** @file  psErrorCodes.c
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-13 20:49:56 $
+ *
+ *  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 found"},
+            {PS_ERR_OS_CALL_FAILED,"unexpected result from an OS standard library call"},
+            //~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
+
+    psS32 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.
+        psListIterator* iter = psListIteratorAlloc(dynamicErrorCodes,PS_LIST_HEAD);
+        while ((desc = (psErrorDescription*)psListGetNext(iter)) != NULL) {
+            if (desc->code == code) {
+                psFree(iter);
+                return desc;
+            }
+        }
+        psFree(iter);
+    }
+    return NULL;
+}
+
+static void freeErrorDescription(psErrorDescription* err)
+{
+    psFree((psPtr)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,
+                     psS32 nerror)
+{
+    if (nerror < 1) {
+        return;
+    }
+
+    if (errors == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION);
+        return;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        dynamicErrorCodes = psListAlloc(NULL);
+        p_psMemSetPersistent(dynamicErrorCodes,true);
+
+        p_psMemSetPersistent(dynamicErrorCodes->iterators,true);
+        p_psMemSetPersistent(dynamicErrorCodes->iterators->data,true);
+        for (int i = 0; i < dynamicErrorCodes->iterators->n;i++) {
+            p_psMemSetPersistent(dynamicErrorCodes->iterators->data[i],true);
+        }
+    }
+
+    for (psS32 i=0;i<nerror;i++) {
+        psErrorDescription* err = psErrorDescriptionAlloc(
+                                      errors[i].code, errors[i].description);
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent((psPtr)err->description,true);
+        if (! psListAdd(dynamicErrorCodes,
+                        PS_LIST_HEAD,
+                        err) ) {
+
+            psError(PS_ERR_UNKNOWN, false,
+                    PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED,
+                    i);
+        }
+        p_psMemSetPersistent(dynamicErrorCodes->head,true);
+        psFree(err);
+    }
+}
+
+psBool 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 psListRemoveData(dynamicErrorCodes,(psPtr)desc);
+}
Index: /branches/rel4/psLib/src/sysUtils/psErrorCodes.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psErrorCodes.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psErrorCodes.h	(revision 3057)
@@ -0,0 +1,111 @@
+/** @file  psErrorCodes.h
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_CODES_H
+#define PS_ERROR_CODES_H
+
+#include "psType.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 found
+    PS_ERR_OS_CALL_FAILED,   ///< unexpected result from an OS standard library call
+    //~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
+    psS32 nerror                         ///< number of errors in input array
+);
+
+/** Clears error codes registered via psErrorRegister.
+ *
+ *  @return psBool    TRUE if given errorcode was removed, otherwise FALSE.
+ */
+psBool p_psErrorUnregister(
+    psErrorCode code                   ///< the error code to find and remove
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/sysUtils/psLogMsg.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psLogMsg.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psLogMsg.c	(revision 3057)
@@ -0,0 +1,391 @@
+/** @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.35 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static psS32 p_psGlobalLogDest;
+    static psS32 p_psGlobalLogLevel;
+    static psS32 p_psLogTime;
+    static psS32 p_psLogHost;
+    static psS32 p_psLogLevel;
+    static psS32 p_psLogName;
+    static psS32 p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.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 psS32 globalLogLevel = PS_LOG_INFO;        // log all messages at this or above
+static psBool logTime = true;     // Flag to include time info
+static psBool logHost = true;     // Flag to include host info
+static psBool logLevel = true;    // Flag to include level info
+static psBool logName = true;     // Flag to include name info
+static psBool logMsg = true;      // Flag to include message info
+
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (psS32): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+psS32 psLogSetLevel(psS32 level)
+{
+    // Save old global log level for changing it.
+    psS32 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 (psS32): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+psBool 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) {
+        psError(PS_ERR_LOCATION_INVALID, true,
+                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;
+        }
+        psError(PS_ERR_LOCATION_INVALID, true,
+                PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID,
+                location);
+        return 1;
+    } else if (strcmp(protocol, "file") == 0) {
+        FILE *file = fopen(location, "w");
+
+        if (file == NULL) {
+            psError(PS_ERR_IO, true,
+                    PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED,
+                    location);
+            return false;
+        }
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = file;
+        return true;
+    }
+
+    psError(PS_ERR_LOCATION_INVALID, true,
+            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:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    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, psS32 level, const char *fmt, va_list ap)
+{
+    static psS32 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
+    psS32 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, psS32 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/rel4/psLib/src/sysUtils/psLogMsg.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psLogMsg.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psLogMsg.h	(revision 3057)
@@ -0,0 +1,117 @@
+/** @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.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  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 "psType.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 psS32     true if set successfully, otherwise false.
+ */
+psBool 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 psS32    old logging level
+ */
+psS32 psLogSetLevel(
+    psS32 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
+    psS32 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
+    psS32 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/rel4/psLib/src/sysUtils/psMemory.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psMemory.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psMemory.c	(revision 3057)
@@ -0,0 +1,697 @@
+/** @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.47 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-13 20:49:56 $
+*
+*  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 <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+#define P_PS_MEMMAGIC (psPtr )0xdeadbeef   // Magic number in psMemBlock header
+
+#define P_PS_LARGE_BLOCK_SIZE 65536        // size where under, we try to recycle
+
+static psS32 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 psS32 recycleBins = 13;
+static psS32 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 psPtr memExhaustedCallbackDefault(size_t size)
+{
+    psPtr ptr = NULL;
+
+    pthread_mutex_lock(&recycleMemBlockListMutex);
+    psS32 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, psS32 lineno)
+{
+    if (ptr->refCounter < 1) {
+        psError(PS_ERR_MEMORY_CORRUPTION, false,
+                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 psS32 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) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_NULL_BLOCK);
+        return 1;
+    }
+
+    if (m->refCounter == 0) {
+        // using an unreferenced block of memory, are you?
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE,
+                m->id);
+        return 1;
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_UNDERFLOW,
+                m->id);
+        return 1;
+    }
+    if (*(psPtr *)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
+        psError(PS_ERR_MEMORY_CORRUPTION, true,
+                PS_ERRORTEXT_psMemory_OVERFLOW,
+                m->id);
+        return 1;
+    }
+
+    return 0;
+}
+
+psS32 psMemCheckCorruption(psBool abort_on_error)
+{
+    psS32 nbad = 0;               // number of bad blocks
+    psBool 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;
+}
+
+psPtr p_psAlloc(size_t size, const char *file, psS32 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.
+        psS32 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(psPtr ));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if (ptr == NULL) {
+                psAbort(__func__, "Failed to allocate %u bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        *(psPtr*)&ptr->startblock = P_PS_MEMMAGIC;
+        *(psPtr*)&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;
+    *(psU32 *)&ptr->lineno = lineno;
+    *(psPtr *)((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
+}
+
+psPtr p_psRealloc(psPtr vptr, size_t size, const char *file, psS32 lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+        psBool isBlockLast = false;
+
+        if (checkMemBlock(ptr, __func__) != 0) {
+            memProblemCallback(ptr, file, lineno);
+            psAbort(file, "Realloc detected a memory corruption (id %lld @ %s:%d).",
+                    ptr->id, ptr->file, ptr->lineno);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock* ) realloc(ptr, sizeof(psMemBlock) + size + sizeof(psPtr ));
+
+        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;
+        *(psPtr *)((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(psPtr vptr, const char *file, psS32 lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+    if (ptr->refCounter < 1) {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+        psAbort(__func__,PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno);
+        psAbort(__func__,"Memory Corruption Detected.");
+    }
+
+    (void)p_psMemDecrRefCounter(vptr, file, lineno);    // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks.
+ */
+psS32 psMemCheckLeaks(psMemoryId id0, psMemBlock* ** arr, FILE * fd, psBool persistence)
+{
+    psS32 nleak = 0;
+    psS32 j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                ( (persistence) || (!persistence && !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, (int)iter->lineno, (long)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) &&
+                ( (persistence) || (!persistence && !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(psPtr vptr)
+{
+    psMemBlock* ptr;
+    psU32 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
+psPtr p_psMemIncrRefCounter(psPtr vptr, const char *file, psS32 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
+psPtr p_psMemDecrRefCounter(psPtr vptr, const char *file, psS32 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) {
+
+            psS32 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(psPtr 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(psPtr vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->freeFcn;
+}
+
+psBool p_psMemGetPersistent(psPtr 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(psPtr vptr,psBool value)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->persistent = value;
+}
Index: /branches/rel4/psLib/src/sysUtils/psMemory.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psMemory.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psMemory.h	(revision 3057)
@@ -0,0 +1,447 @@
+/** @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.32 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-22 20:49:59 $
+ *
+ *  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 <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#include "psType.h"
+
+/** @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 psU64 psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef psU64 psReferenceCount;
+
+/// typedef for deallocator.
+typedef void (*psFreeFcn) (psPtr 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 psPtr 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 psS32 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
+    psBool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
+    const psPtr 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
+    psS32 lineno                         ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return psPtr pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psPtr (*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 psPtr pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree 
+ */
+#ifdef DOXYGEN
+psPtr psAlloc(size_t size       ///< Size required
+             );
+#else
+
+psPtr p_psAlloc(size_t size,    ///< Size required
+                const char *file,       ///< File of call
+                psS32 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(
+    psPtr 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(
+    psPtr 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(
+    psPtr ptr,                         ///< the memory block to operate on
+    psBool 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 psBool    true if memory is marked persistent, otherwise false.
+ */
+psBool p_psMemGetPersistent(
+    psPtr ptr                          ///< the memory block to check.
+);
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return psPtr pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+psPtr psRealloc(
+    psPtr ptr                          ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+);
+#else
+
+psPtr p_psRealloc(
+    psPtr ptr,                         ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+    const char *file,                  ///< File of call
+    psS32 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(
+    psPtr ptr,                         ///< Pointer to free, if NULL, function returns immediately.
+);
+#else
+
+void p_psFree(
+    psPtr ptr,                        ///< Pointer to free
+    const char *file,                 ///< File of call
+    psS32 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 psS32  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
+ */
+psS32 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)
+    psBool persistence                 ///< make check across all object even persistent ones
+);
+
+/** 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
+ */
+psS32 psMemCheckCorruption(
+    psBool abort_on_error                ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    psPtr vptr                         ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+#ifdef DOXYGEN
+psPtr psMemIncrRefCounter(
+    psPtr vptr                         ///< Pointer to increment refCounter, and return
+);
+#else
+
+psPtr p_psMemIncrRefCounter(
+    psPtr vptr,                        ///< Pointer to increment refCounter, and return
+    const char *file,                  ///< File of call
+    psS32 lineno                         ///< Line number of call
+);
+
+#define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ *
+ *  @return psPtr    the pointer deremented in refCount, or NULL if pointer is 
+ *                   fully dereferenced.
+ */
+#ifdef DOXYGEN
+psPtr psMemDecrRefCounter(
+    psPtr vptr                         ///< Pointer to decrement refCounter, and return
+);
+#else
+
+psPtr p_psMemDecrRefCounter(
+    psPtr vptr,                        ///< Pointer to decrement refCounter, and return
+    const char *file,                  ///< File of call
+    psS32 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/rel4/psLib/src/sysUtils/psString.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psString.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psString.c	(revision 3057)
@@ -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.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:05:00 $
+ *
+ *  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, psS32 nChar)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if (nChar < 0) {
+        // Log error message and return NULL
+        psError(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/rel4/psLib/src/sysUtils/psString.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psString.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psString.h	(revision 3057)
@@ -0,0 +1,71 @@
+/** @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.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+#include "psType.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 */
+
+    psS32 nChar
+    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.dat
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.dat	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.dat	(revision 3057)
@@ -0,0 +1,50 @@
+#
+#  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 %lld was freed but still being used.
+psMemory_UNDERFLOW                     Memory block %lld is corrupted; buffer underflow detected.
+psMemory_OVERFLOW                      Memory block %lld is corrupted; buffer overflow detected.
+psMemory_MULTIPLE_FREE                 Block %lld, 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.
+#
+# Error Messages from psConfigure.c
+#
+psConfigure_INITIALIZATION_FAILED      Failed to initialize %s.
+psConfigure_FINALIZATION_FAILED        Failed to finalize %s.
+
Index: /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psSysUtilsErrors.h	(revision 3057)
@@ -0,0 +1,54 @@
+/** @file  psSysUtilsErrors.h
+ *
+ *  @brief Contains the error text for the system utility functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-02 21:12:52 $
+ *
+ *  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 %lld was freed but still being used."
+#define PS_ERRORTEXT_psMemory_UNDERFLOW "Memory block %lld is corrupted; buffer underflow detected."
+#define PS_ERRORTEXT_psMemory_OVERFLOW "Memory block %lld is corrupted; buffer overflow detected."
+#define PS_ERRORTEXT_psMemory_MULTIPLE_FREE "Block %lld, 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."
+#define PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED "Failed to initialize %s."
+#define PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED "Failed to finalize %s."
+//~End
+
+#endif
Index: /branches/rel4/psLib/src/sysUtils/psTrace.c
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psTrace.c	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psTrace.c	(revision 3057)
@@ -0,0 +1,531 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.40 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-02 21:12:52 $
+ *
+ *  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 psS64 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, psS32 level);
+
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+static p_psComponent* componentAlloc(const char *name, psS32 level)
+{
+    p_psComponent* comp = psAlloc(sizeof(p_psComponent));
+
+    p_psMemSetPersistent(comp,true);
+    p_psMemSetDeallocator(comp, (psFreeFcn) componentFree);
+    comp->name = psStringCopy(name);
+    p_psMemSetPersistent((psPtr)comp->name,true);
+    comp->level = level;
+    comp->n = 0;
+    comp->p_psSpecified = false;
+    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 (psS32 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((psPtr)comp->name,false);
+    psFree((psPtr)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)
+{
+    psS32 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 psBool componentAdd(const char *addNodeName, psS32 level)
+{
+    psS32 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;
+    psS32 nodeExists = 0;
+
+    // XXX: Verify that this is the correct behavior.
+    if (strcmp("", addNodeName) == 0) {
+        psError(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] != '.') {
+        psError(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
+*****************************************************************************/
+psBool psTraceSetLevel(const char *comp,   // component of interest
+                       psS32 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) ) {
+        psError(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 psS32 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;
+    psS32 i = 0;
+    psS32 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.
+ *****************************************************************************/
+psS32 psTraceGetLevel(const char *name)
+{
+    char *compName = NULL;
+    psS32 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);
+    }
+
+    // XXX: The default trace level is currently set at -1, which is not a
+    // valid trace level.  This is convenient in determining whether or not
+    // a component should inherit the trace level from parent nodes.  However,
+    // it's not clear that -1 should ever be returned by this function.
+    // The SDR is unclear on this point and we should probably request IfA
+    // comment.
+    if (traceLevel == PS_DEFAULT_TRACE_LEVEL) {
+        traceLevel = PS_THE_OTHER_DEFAULT_TRACE_LEVEL;
+    }
+
+    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,
+                               psS32 depth,
+                               psS32 defLevel)
+{
+    psS32 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_THE_OTHER_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
+               psS32 level,       // desired trace level
+               ...)             // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    psS32 i = 0;
+
+    if (NULL == comp) {
+        psError(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/rel4/psLib/src/sysUtils/psTrace.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psTrace.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psTrace.h	(revision 3057)
@@ -0,0 +1,94 @@
+/** @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 GLG, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-24 20:12:28 $
+ *
+ *  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
+#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL 0
+
+/** \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
+        psS32 level;                  // trace level for this component
+        bool p_psSpecified;
+        psS32 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
+               psS32 myLevel,     ///< desired trace level
+               ...)             ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+psBool psTraceSetLevel(const char *facil,     ///< facilty of interest
+                       psS32 level)     ///< desired trace level
+;
+
+/// Get the trace level
+psS32 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/rel4/psLib/src/sysUtils/psType.h
===================================================================
--- /branches/rel4/psLib/src/sysUtils/psType.h	(revision 3057)
+++ /branches/rel4/psLib/src/sysUtils/psType.h	(revision 3057)
@@ -0,0 +1,236 @@
+
+/** @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.27 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:21 $
+*
+*  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>
+#include <stdbool.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 bool psBool;                   ///< boolean value
+
+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 psS16 integer.
+    PS_TYPE_U32  = 0x0304,             ///< Unsigned integer.
+    PS_TYPE_U64  = 0x0308,             ///< Unsigned psS64 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_BOOL = 0x1301,             ///< Boolean.
+    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
+typedef psBool psBOOL;                 ///< allow psBOOL to be used instead of psBool (for macros)
+
+#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_BOOL_NAME "psBool"
+#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_BOOL: \
+    value = PS_TYPE_BOOL_NAME; \
+    break; \
+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 if the psElemType is boolean type.
+#define PS_IS_PSELEMTYPE_BOOL(x) ((x & 0x1000) == 0x1000)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(psPtr) :(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;
+
+/** The type of a basic data type
+ *
+ *  All psLib complex types consist of primitive components.  This structure provides the ability to cast
+ *  an unknown data structure to safely test the underlining data type.
+ *
+ */
+typedef struct
+{
+    psType  type;              ///< Data type information
+}
+psMath;
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/types/psArray.c
===================================================================
--- /branches/rel4/psLib/src/types/psArray.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psArray.c	(revision 3057)
@@ -0,0 +1,158 @@
+
+/** @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.22 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-30 20:18:36 $
+ *
+ *  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);
+
+static void arrayFree(psArray* restrict psArr)
+{
+    if (psArr == NULL) {
+        return;
+    }
+
+    psArrayElementFree(psArr);
+
+    psFree(psArr->data);
+}
+
+/*****************************************************************************
+  FUNCTION IMPLEMENTATION - PUBLIC
+ *****************************************************************************/
+psArray* psArrayAlloc(psU32 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, psU32 nalloc)
+{
+    if (in == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL,true,PS_ERRORTEXT_psArray_REALLOC_NULL);
+        return NULL;
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        if (nalloc < in->n) {
+            for (psS32 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;
+}
+
+psArray* psArrayAdd(psArray* psArr,
+                    int delta,
+                    psPtr data)
+{
+    if (psArr == NULL) {
+        return psArr;
+    }
+
+    int n = psArr->n;
+
+    if (n >= psArr->nalloc) {
+        // array needs to be expanded to make room for more elements
+        int d = (delta > 0) ? delta : 10; // as spec'ed in SDRS.
+        psArr = psArrayRealloc(psArr, n+d);
+    }
+
+    // add the element to the end of the array.
+    psArr->data[n] = data;
+    psArr->n = n+1;
+
+    return psArr;
+}
+
+psBool psArrayRemove(psArray* psArr,
+                     psPtr data)
+{
+    psBool success = false;
+
+    if (psArr == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psArray_ARRAY_NULL);
+        return false;
+    }
+
+    psS32 n = psArr->n;
+    psPtr* psArrData = psArr->data;
+    for (psS32 i = n-1; i >= 0; i--) {
+        if (psArrData[i] == data) {
+            memmove(&psArr->data[i],&psArr->data[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 (psS32 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/rel4/psLib/src/types/psArray.h
===================================================================
--- /branches/rel4/psLib/src/types/psArray.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psArray.h	(revision 3057)
@@ -0,0 +1,130 @@
+
+/** @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.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 01:14:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ARRAY_H
+#define PS_ARRAY_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
+{
+    psU32 nalloc;        ///< Total number of elements available.
+    psU32 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(
+    psU32 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.
+    psU32 nalloc                       ///< Total number of elements to make available.
+);
+
+/** Add an element to the end the array, expanding the array storage if
+ *  necessary.
+ *
+ *  @return psArray*        The array with the element added
+ */
+psArray* psArrayAdd(
+    psArray* psArr,                    ///< array to operate on
+    int delta,
+    ///< the amount to expand array, if necessary.  If less than one, 10 will be used.
+    psPtr data                         ///< the data pointer to add to psArray
+);
+
+/** 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.
+ *
+ */
+psBool 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/rel4/psLib/src/types/psBitSet.c
===================================================================
--- /branches/rel4/psLib/src/types/psBitSet.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psBitSet.c	(revision 3057)
@@ -0,0 +1,306 @@
+/** @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.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 01:04:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.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(psS32 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(psS32 n)
+{
+    psS32 numBytes = 0;
+    psBitSet* newObj = NULL;
+
+    if (n < 0) {
+        psError(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,
+                      psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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,
+                        psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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;
+}
+
+psBool psBitSetTest(const psBitSet* inBitSet,
+                    psS32 bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_SET_NULL);
+        return false;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psError(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)
+{
+    psS32 i = 0;
+    psS32 n = 0;
+    char* outBits = NULL;
+    char* inBits1 = NULL;
+    char* inBits2 = NULL;
+    psS32 op = UNKNOWN_OP;
+
+    if (inBitSet1 == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+    inBits1 = inBitSet1->bits;
+
+    if (operator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_OPERATOR_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    // make operator all caps
+    psS32 tempStrLen = strlen(operator);
+    char* tempStr = psAlloc(tempStrLen+1);
+
+    for (psS32 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);
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psBitSet_OPERATOR_INVALID,
+                operator);
+        return NULL;
+    }
+    psFree(tempStr);
+
+    if (op != NOT_OP) {
+        if (inBitSet2 == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                    PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL);
+            psFree(outBitSet);
+            return NULL;
+        }
+
+        if (inBitSet1->n != inBitSet2->n) {
+            psError(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) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psBitSet_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    outBitSet = psBitSetOp(outBitSet,inBitSet,"NOT",NULL);
+
+    if (outBitSet == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                PS_ERRORTEXT_psBitSet_NOT_OP_FAILED);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet* restrict inBitSet)
+{
+    psS32 i = 0;
+    psS32 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/rel4/psLib/src/types/psBitSet.h
===================================================================
--- /branches/rel4/psLib/src/types/psBitSet.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psBitSet.h	(revision 3057)
@@ -0,0 +1,145 @@
+/** @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.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-27 00:57:31 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+#include "psType.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
+{
+    psS32 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(
+    psS32 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.
+    psS32 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.
+    psS32 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.
+ */
+
+psBool psBitSetTest(
+    const psBitSet* restrict inMask,   ///< Pointer psBitSet to be tested.
+    psS32 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/rel4/psLib/src/types/psHash.c
===================================================================
--- /branches/rel4/psLib/src/types/psHash.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psHash.c	(revision 3057)
@@ -0,0 +1,466 @@
+
+/** @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
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-03 20:28:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "psHash.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psTrace.h"
+#include "psError.h"
+
+#include "psCollectionsErrors.h"
+
+static psHashBucket* hashBucketAlloc(const char *key, psPtr data, psHashBucket* next);
+static void hashBucketFree(psHashBucket* bucket);
+static psPtr doHashWork(psHash* table, const char *key, psPtr data, psBool 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)
+{
+    psS32 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,
+                                     psPtr 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(psS32 nbucket)        // initial number of buckets
+{
+    psS32 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;
+}
+
+/******************************************************************************
+hashFree(table): 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)
+{
+    psS32 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 psPtr doHashWork(psHash* table,
+                        const char *key,
+                        psPtr data, psBool remove
+                           )
+{
+    psS64 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)) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    // NOTE: This is the originally supplied hash function.
+    // for (psS32 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)) {
+        psError(PS_ERR_UNKNOWN, true,
+                "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.
+
+                    psPtr 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;
+    }
+}
+
+/******************************************************************************
+psHashAdd(table, key, data): 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.
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+psBool psHashAdd(psHash* table,
+                 const char *key,
+                 psPtr data)
+{
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_DATA_NULL);
+        return false;
+    }
+
+    return (doHashWork(table, key, data, false) != 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.
+ *****************************************************************************/
+psPtr psHashLookup(psHash* table,      // table to lookup key in
+                   const char *key)     // key to lookup
+{
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+
+    return doHashWork(table, key, NULL, false);
+}
+
+/******************************************************************************
+psHashRemove(table, key): 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
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+psBool psHashRemove(psHash* table,
+                    const char *key)
+{
+    psPtr data = NULL;
+    psBool retVal = false;
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+
+    data = doHashWork(table, key, NULL, true);
+    if (data != NULL) {
+        retVal = true;
+    } else {
+        retVal = false;
+    }
+
+    return retVal;
+}
+
+psArray* psHashToArray(psHash* table)
+{
+
+    if (table == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+
+    // first, let's just count the number of data elements to know what size
+    // psArray we need to allocate.
+    int nElements = 0;
+    int nbucket = table->nbucket;
+    for (int i = 0; i < nbucket; i++) {
+        psHashBucket* tmpBucket = table->buckets[i];
+        while (tmpBucket != NULL) {
+            nElements++;
+            tmpBucket = tmpBucket->next;
+        }
+    }
+
+    psArray* result = psArrayAlloc(nElements);
+    result->n = nElements;
+
+    // now fill in the array with the hash table's data
+    psPtr* data = result->data;
+    for (int i = 0; i < nbucket; i++) {
+        psHashBucket* tmpBucket = table->buckets[i];
+        while (tmpBucket != NULL) {
+            *(data++) = psMemIncrRefCounter(tmpBucket->data);
+            tmpBucket = tmpBucket->next;
+        }
+    }
+
+    return result;
+}
Index: /branches/rel4/psLib/src/types/psHash.h
===================================================================
--- /branches/rel4/psLib/src/types/psHash.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psHash.h	(revision 3057)
@@ -0,0 +1,86 @@
+
+/** @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
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-03 20:28:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_HASH_H)
+#define PS_HASH_H
+
+/** \addtogroup HashTable
+ *  \{
+ */
+
+#include "psList.h"
+
+/** A bucket that holds an item of data. */
+typedef struct psHashBucket
+{
+    char *key;                         ///< key for this item of data
+    psPtr 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
+{
+    psS32 nbucket;                     ///< Number of buckets in hash table.
+    psHashBucket* *buckets;            ///< The bucket data.
+}
+psHash;
+
+/// Allocate hash buckets in table.
+psHash* psHashAlloc(
+    psS32 nbucket                  ///< The number of buckets to allocate.
+);
+
+/// Insert entry into table.
+psBool psHashAdd(
+    psHash* table,                 ///< table to insert in
+    const char *key,               ///< key to use
+    psPtr data                     ///< data to insert
+);
+
+/// Lookup key in table.
+psPtr psHashLookup(
+    psHash* table,                 ///< table to lookup key in
+    const char *key                ///< key to lookup
+);
+
+/// Remove key from table.
+psBool 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.
+);
+
+/** Create a psArray from a psHash contents.
+ *
+ *  @return psArray*       A new psArray with duplicate contents of the input psHash
+ */
+psArray* psHashToArray(
+    psHash* table                  ///< table to convert to psArray
+);
+
+/* \} */// End of DataGroup Functions
+
+#endif
Index: /branches/rel4/psLib/src/types/psList.c
===================================================================
--- /branches/rel4/psLib/src/types/psList.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psList.c	(revision 3057)
@@ -0,0 +1,601 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup LinkedList
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-11 01:24:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.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 ((psPtr )1)         // next iteration should return head
+#define ITER_INIT_TAIL ((psPtr )2)         // next iteration should return tail
+
+// private functions.
+static void listFree(psList* list);
+static void listIteratorFree(psListIterator* iter);
+static psBool listIteratorRemove(psListIterator* iterator);
+
+static void listFree(psList* list)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // remove the free function of iterators to avoid double removal from list
+    psArray* iterators = list->iterators;
+    for (int i = 0; i < iterators->n; i++) {
+        p_psMemSetDeallocator(iterators->data[i], NULL);
+    }
+
+    psFree(list->iterators);
+
+    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)
+    ;
+
+}
+
+static void listIteratorFree(psListIterator* iter)
+{
+    if (iter == NULL) {
+        return;
+    }
+
+    // remove this iterator from the parent list
+    psArrayRemove(iter->list->iterators,iter);
+
+}
+
+static psBool listIteratorRemove(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return false;
+    }
+
+    psListElem* elem = iterator->cursor;
+    psList* list = iterator->list;
+    int index = iterator->index;
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (elem == list->head) {        // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem == list->tail) {        // tail of list?
+        list->tail = elem->prev;
+    } else {
+        elem->next->prev = elem->prev;
+    }
+
+    psArray* iterators = list->iterators;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->cursor == elem) {
+            iter->cursor = NULL;
+        } else if (iter->index > index && iter->index > 0) {
+            iter->index--;
+        }
+    }
+
+    list->size--;
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    // OK, delete orphaned list element and its data
+    psFree(elem->data);
+    psFree(elem);
+
+    return true;
+}
+
+psList* psListAlloc(psPtr data)
+{
+    psList* list = psAlloc(sizeof(psList));
+
+    p_psMemSetDeallocator(list, (psFreeFcn) listFree);
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iterators = psArrayAlloc(16);
+    list->iterators->n = 0;
+
+    // create a default iterator
+    psListIteratorAlloc(list,PS_LIST_HEAD);
+
+    pthread_mutex_init(&(list->lock), NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, PS_LIST_TAIL, data);
+    }
+
+    return list;
+}
+
+psListIterator* psListIteratorAlloc(psList* list, int location)
+{
+    psListIterator* iter = psAlloc(sizeof(psListIterator));
+
+    p_psMemSetDeallocator(iter, (psFreeFcn) listIteratorFree);
+
+    // initialize the attributes
+    iter->list = list;
+    iter->cursor = NULL;
+    iter->index = 0;
+    iter->offEnd = false;
+
+    // add to the list's array of iterators
+    psArray* listIterators = list->iterators;
+    int num = listIterators->n;
+    if ( num >= listIterators->nalloc) {
+        // need to resize the array to make more room for another iterator.
+        list->iterators = psArrayRealloc(listIterators,listIterators->nalloc*2);
+        listIterators = list->iterators;
+    }
+    listIterators->data[num] = iter;
+    listIterators->n = num+1;
+
+    if (! psListIteratorSet(iter,location)) {
+        psFree(iter);
+        iter = NULL;
+    }
+
+    return iter;
+}
+
+psBool psListIteratorSet(psListIterator* iterator,
+                         int location)
+{
+    if (iterator == NULL) {
+        return false;
+    }
+
+    psList* list = iterator->list;
+
+    if (location == PS_LIST_TAIL) {
+        iterator->cursor = list->tail;
+        iterator->index = list->size - 1;
+        iterator->offEnd = false;
+        return true;
+    }
+
+    if (location == PS_LIST_HEAD) {
+        iterator->cursor = list->head;
+        iterator->index = 0;
+        iterator->offEnd = false;
+        return true;
+    }
+
+    if (location < 0 || location >= (int)list->size) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_LOCATION_INVALID,
+                location);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    int index = iterator->index;
+    if (cursor == NULL) {      // set the cursor to the head if it is NULL
+        if (location > list->size/2) { // closer to tail or head?
+            cursor = list->tail;
+            index = list->size - 1;
+        } else {
+            cursor = list->head;
+            index = 0;
+        }
+    }
+
+    if (location < index) {
+        psS32 diff = index - location;
+
+        for (psS32 count = 0; count < diff; count++) {
+            cursor = cursor->prev; // shouldn't need to check for NULL
+        }
+    } else {
+        psS32 diff = location - index;
+
+        for (psS32 count = 0; count < diff; count++) {
+            cursor = cursor->next; // shouldn't need to check for NULL
+        }
+    }
+    iterator->cursor = cursor;
+    iterator->index = location;
+    iterator->offEnd = false;
+
+    return true;
+}
+
+psBool psListAdd(psList* list, psS32 location, psPtr data)
+{
+
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (location > 0 && location >= (int)list->size) {
+        psLogMsg(__func__,PS_LOG_WARN,
+                 "Specified location, %d, is beyond the end of the list.  "
+                 "Adding data item to tail.",
+                 location);
+        location = PS_LIST_TAIL;
+    }
+
+    // move ourselves to the given position
+    if (! psListIteratorSet(list->iterators->data[0],location)) {
+        return false;
+    }
+
+    if (location == PS_LIST_TAIL) {
+        // insert the element at the end of the list
+        return psListAddAfter(list->iterators->data[0],data);
+    } else {
+        return psListAddBefore(list->iterators->data[0],data);
+    }
+}
+
+bool psListAddAfter(psListIterator* iterator, void* data)
+{
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (iterator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_ITERATOR_NULL);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    psList* list = iterator->list;
+
+    if (cursor == NULL && list->head != NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_ITERATOR_INVALID);
+        return false;
+    }
+
+    psListElem* elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // set the new list element's attributes
+    if (cursor == NULL) { // must be an empty list
+        elem->prev = NULL;
+        elem->next = NULL;
+        list->head = elem;
+        list->tail = elem;
+    } else {
+        elem->prev = cursor;
+        elem->next = cursor->next;
+        cursor->next = elem;
+        if (elem->next == NULL) {
+            list->tail = elem;
+        } else {
+            elem->next->prev = elem;
+        }
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    list->size++;
+
+    if (cursor == list->tail) {
+        list->tail = elem;
+    }
+
+    psArray* iterators = list->iterators;
+    int index = iterator->index;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->index > index) {
+            iter->index++;
+        }
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+bool psListAddBefore(psListIterator* iterator, void* data)
+{
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    if (iterator == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_ITERATOR_NULL);
+        return false;
+    }
+
+    psListElem* cursor = iterator->cursor;
+    psList* list = iterator->list;
+
+    if (cursor == NULL && list->head != NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_ITERATOR_INVALID);
+        return false;
+    }
+
+    psListElem* elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    // set the new list element's attributes
+    if (cursor == NULL) { // empty list.
+        elem->prev = NULL;
+        elem->next = NULL;
+        list->head = elem;
+        list->tail = elem;
+    } else {
+        elem->prev = cursor->prev;
+        elem->next = cursor;
+        cursor->prev = elem;
+        if (elem->prev == NULL) {
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    list->size++;
+
+    if (cursor == list->head) {
+        list->head = elem;
+    }
+
+    psArray* iterators = list->iterators;
+    int index = iterator->index;
+    for (int i = 0; i < iterators->n; i++) {
+        psListIterator* iter = (psListIterator*) iterators->data[i];
+        if (iter->index >= index) {
+            iter->index++;
+        }
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+psBool psListRemove(psList* list,
+                    psS32 location)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    // move ourselves to the given position
+    psListIterator* defaultIterator = list->iterators->data[0];
+    if (! psListIteratorSet(defaultIterator,location)) {
+        return false;
+    }
+
+    return listIteratorRemove(defaultIterator);
+}
+
+psBool psListRemoveData(psList* list,
+                        psPtr data)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return false;
+    }
+
+    if (data == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NULL);
+        return false;
+    }
+
+    psListElem* elem = list->head;
+    int index = 0;
+    while (elem != NULL && elem->data != data) {
+        elem = elem->next;
+        index++;
+    }
+    if (elem == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_DATA_NOT_FOUND);
+        return false;
+    }
+
+    psListIterator* iterator = (psListIterator*)list->iterators->data[0];
+    iterator->index = index;
+    iterator->cursor = elem;
+
+    return listIteratorRemove(iterator);
+}
+
+psPtr psListGet(psList* list, psS32 location)
+{
+    if (list == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psList_LIST_NULL);
+        return NULL;
+    }
+
+    if (list->head == NULL) { // list empty?
+        return NULL;
+    }
+
+    psListIterator* iterator = list->iterators->data[0];
+
+    if (! psListIteratorSet(iterator,location)) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psList_LOCATION_INVALID,
+                location);
+        return NULL;
+    }
+
+    return iterator->cursor->data;
+}
+
+/*
+ * and now return the previous/next element of the list
+ */
+psPtr psListGetNext(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return NULL;
+    }
+
+    psPtr data = iterator->cursor->data;
+
+    iterator->cursor = iterator->cursor->next;
+    iterator->index++;
+    if (iterator->cursor == NULL) {
+        iterator->offEnd = true;
+    }
+
+    return data;
+}
+
+psPtr psListGetPrevious(psListIterator* iterator)
+{
+    if (iterator == NULL || iterator->cursor == NULL) {
+        return NULL;
+    }
+
+    psPtr data = iterator->cursor->data;
+
+    iterator->cursor = iterator->cursor->prev;
+    iterator->index--;
+
+    return data;
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psArray* psListToArray(psList* restrict list)
+{
+    psListElem* ptr;
+    psU32 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 (psS32 i = 0; i < n; i++) {
+        arr->data[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psArrayToList(psArray* arr)
+{
+    psU32 n;
+    psList* list;               // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (psS32 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);
+    psArray* iterators = psMemIncrRefCounter(list->iterators);
+    psFree(list);
+
+    arr = psArraySort(arr, compare);
+
+    // convert back to linked list
+    list = psArrayToList(arr);
+    psFree(list->iterators);
+    list->iterators = iterators;
+    psFree(arr);
+
+    // sorting should invalidate all iterator positions.
+    for (int i = 0; i < iterators->n; i++) {
+        ((psListIterator*)iterators->data[i])->cursor = NULL;
+    }
+
+    return list;
+}
Index: /branches/rel4/psLib/src/types/psList.h
===================================================================
--- /branches/rel4/psLib/src/types/psList.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psList.h	(revision 3057)
@@ -0,0 +1,226 @@
+#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.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-10 02:50:14 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+#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
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem* prev;           ///< previous link in list
+    struct psListElem* next;           ///< next link in list
+    psPtr 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
+ */
+typedef struct
+{
+    psU32 size;                        ///< number of elements on list
+    psListElem* head;                  ///< first element on list (may be NULL)
+    psListElem* tail;                  ///< last element on list (may be NULL)
+    psArray* iterators;
+    ///< array of all iterators associated with this list.  First iterator is
+    ///< used internally to improve performance when using indexed access, all
+    ///< others are user-level iterators created by psListIteratorAlloc.
+
+    pthread_mutex_t lock;              ///< mutex to lock a node during changes
+}
+psList;
+
+/** The psList iterator structure.  This should be allocated via
+ *  psListIteratorAlloc and not directly.
+ *
+ *  The life span of a psListIterator object is ended by either a psFree
+ *  of this structure OR psFree of the psList in which it operates on.
+ *
+ *  @see psListIteratorAlloc, psListIteratorSet, psListGetNext, psListGetPrevious
+ */
+typedef struct
+{
+psList* list;                      ///< List iterator to works on
+psListElem* cursor;                ///< current cursor position
+int index;                         ///< the index number in the list
+bool offEnd;                       ///< Iterator off the end?
+}
+psListIterator;
+
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList* A new psList object.
+ */
+psList* psListAlloc(
+    psPtr data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+/** Creates a psListIterator object and associates it with a psList.
+ *
+ *  @return psListIterator* A new psListIterator object.
+ */
+psListIterator* psListIteratorAlloc(
+    psList* list,                      ///< the psList to iterate with
+    int location                       ///< the initial starting point.
+    ///<  This can be a numeric index, PS_LIST_HEAD, or PS_LIST_TAIL.
+);
+
+/** Set the iterator of the list to a given position.  If location is invalid the
+ *  iterator position is not changed.
+ *
+ *  @return psBool        TRUE if iterator successfully set, otherwise FALSE.
+ */
+psBool psListIteratorSet(
+    psListIterator* iterator,            ///< list iterator
+    int location                         ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAdd(
+    psList* restrict list,             ///< list to add item to
+    psS32 location,                    ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Adds an data item to a psList at position just after the list position given
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAddAfter(
+    psListIterator* list,              ///< list position to add item to
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Adds an data item to a psList at position just before the list position given
+ *
+ *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
+ */
+psBool psListAddBefore(
+    psListIterator* list,              ///< list position to add item to
+    psPtr data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Remove an item at the specified location from a list.
+ *
+ *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+psBool psListRemove(
+    psList* restrict list,             ///< list to remove element from
+    psS32 location                     ///< index of item
+);
+
+/** Remove an item from a list.
+ *
+ *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+psBool psListRemoveData(
+    psList* restrict list,             ///< list to remove element from
+    psPtr data                         ///< data item to find and remove
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return psPtr       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.
+ */
+psPtr psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    psS32 location                     ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Position the specified iterator to the next item in list.
+ *
+ *  @return psPtr       the data item at the new iterator position or NULL if the
+ *                      iterator goes past the end of the list.
+ */
+psPtr psListGetNext(
+    psListIterator* restrict iterator  ///< iterator to move
+);
+
+/** Position the specified iterator to the previous item in list.
+ *
+ *  @return psPtr       the data item at the new iterator position or NULL if the
+ *                      iterator goes past the beginning of the list.
+ */
+psPtr psListGetPrevious(
+    psListIterator* restrict iterator  ///< iterator to move
+);
+
+/** 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/rel4/psLib/src/types/psLookupTable.c
===================================================================
--- /branches/rel4/psLib/src/types/psLookupTable.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psLookupTable.c	(revision 3057)
@@ -0,0 +1,670 @@
+/** @file  psLookupTable.c
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-16 18:53:02 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef DARWIN
+#undef __STRICT_ANSI__
+#endif
+#include <stdlib.h>
+#ifdef DARWIN
+#define __STRICT_ANSI__
+#endif
+#include <math.h>
+
+#include "psMemory.h"
+#include "psString.h"
+#include "psError.h"
+#include "psLookupTable.h"
+#include "psFileUtilsErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static bool ignoreLine(char *inString);
+static char *cleanString(char *inString, int sLen);
+static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
+static psU8 parseU8(char *inString, psParseErrorType *status);
+static psS8 parseS8(char *inString, psParseErrorType *status);
+static psU16 parseU16(char *inString, psParseErrorType *status);
+static psS16 parseS16(char *inString, psParseErrorType *status);
+static psU32 parseU32(char *inString, psParseErrorType *status);
+static psS32 parseS32(char *inString, psParseErrorType *status);
+static psU64 parseU64(char *inString, psParseErrorType *status);
+static psS64 parseS64(char *inString, psParseErrorType *status);
+static psF32 parseF32(char *inString, psParseErrorType *status);
+static psF64 parseF64(char *inString, psParseErrorType *status);
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);
+static void lookupTableFree(psLookupTable* table);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+static 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. */
+static 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;
+}
+
+
+/** 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. */
+static char* getToken(char **inString, char *delimiter, psParseErrorType *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 = PS_PARSE_ERROR_GENERAL;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a psU8. The input string must be cleaned and null terminated. */
+static psU8 parseU8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU8 value = 0.0;
+
+
+    value = (psU8)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS8. The input string must be cleaned and null terminated. */
+static psS8 parseS8(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS8 value = 0.0;
+
+
+    value = (psS8)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU16. The input string must be cleaned and null terminated. */
+static psU16 parseU16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU16 value = 0.0;
+
+
+    value = (psU16)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS16. The input string must be cleaned and null terminated. */
+static psS16 parseS16(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS16 value = 0.0;
+
+
+    value = (psS16)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU32. The input string must be cleaned and null terminated. */
+static psU32 parseU32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU32 value = 0.0;
+
+
+    value = (psU32)strtoul(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS32. The input string must be cleaned and null terminated. */
+static psS32 parseS32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS32 value = 0.0;
+
+
+    value = (psS32)strtol(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psU64. The input string must be cleaned and null terminated. */
+static psU64 parseU64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psU64 value = 0.0;
+
+
+    value = (psU64)strtoull(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psS64. The input string must be cleaned and null terminated. */
+static psS64 parseS64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psS64 value = 0.0;
+
+
+    value = (psS64)strtoll(inString, &end, 0);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF32. The input string must be cleaned and null terminated. */
+static psF32 parseF32(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF32 value = 0.0;
+
+
+    value = (psF32)strtof(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a psF64. The input string must be cleaned and null terminated. */
+static psF64 parseF64(char *inString, psParseErrorType *status)
+{
+    char *end = NULL;
+    psF64 value = 0.0;
+
+
+    value = (psF64)strtod(inString, &end);
+    if(*end != '\0') {
+        *status = PS_PARSE_ERROR_VALUE;
+    } else if(inString==end) {
+        *status = PS_PARSE_ERROR_VALUE;
+    }
+
+    return value;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status)
+{
+    psElemType type;
+
+
+    if(vec == NULL) {
+        *status = 1;
+        return;
+    }
+
+    type = vec->type.type;
+
+    switch(type) {
+    case PS_TYPE_U8:
+        vec->data.U8[index] = parseU8(strValue, status);
+        break;
+    case PS_TYPE_S8:
+        vec->data.S8[index] = parseS8(strValue, status);
+        break;
+    case PS_TYPE_U16:
+        vec->data.U16[index] = parseU16(strValue, status);
+        break;
+    case PS_TYPE_S16:
+        vec->data.S16[index] = parseS16(strValue, status);
+        break;
+    case PS_TYPE_U32:
+        vec->data.U32[index] = parseU32(strValue, status);
+        break;
+    case PS_TYPE_S32:
+        vec->data.S32[index] = parseS32(strValue, status);
+        break;
+    case PS_TYPE_U64:
+        vec->data.U64[index] = parseU64(strValue, status);
+        break;
+    case PS_TYPE_S64:
+        vec->data.S64[index] = parseS64(strValue, status);
+        break;
+    case PS_TYPE_F32:
+        vec->data.F32[index] = parseF32(strValue, status);
+        break;
+    case PS_TYPE_F64:
+        vec->data.F64[index] = parseF64(strValue, status);
+        break;
+    default:
+        *status = PS_PARSE_ERROR_TYPE;
+    }
+
+    return;
+}
+
+static psParseErrorType printError(psU64 lineCount, char* badText, psParseErrorType status)
+{
+    switch(status) {
+    case PS_PARSE_ERROR_VALUE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_VALUE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_TYPE:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_TYPE, badText, lineCount);
+        break;
+    case PS_PARSE_ERROR_GENERAL:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_PARSE_GENERAL, badText, lineCount);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INVALID_TYPE, badText, lineCount);
+    }
+
+    return PS_LOOKUP_SUCCESS;
+}
+
+static void lookupTableFree(psLookupTable* table)
+{
+    if (table == NULL) {
+        return;
+    }
+
+    psFree(table->values);
+    psFree(table->index);
+    psFree((char*)table->fileName);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psLookupTable* psLookupTableAlloc(const char *fileName, psF64 validFrom, psF64 validTo)
+{
+    psLookupTable *outTable = NULL;
+
+
+    // Can't read table if you don't know its name
+    PS_PTR_CHECK_NULL(fileName,NULL);
+
+    // Allocate lookup table
+    outTable = (psLookupTable*)psAlloc(sizeof(psLookupTable));
+
+    // Set deallocator
+    p_psMemSetDeallocator(outTable, (psFreeFcn)lookupTableFree);
+
+    // Allocate and set metadata item comment
+    outTable->fileName = psStringCopy(fileName);
+
+    // Number of table rows and columns. Automatically resized by table read.
+    outTable->numRows = 0;
+    outTable->numCols = 0;
+
+    // Valid ranges. Automatically set by table read if both zero.
+    outTable->validFrom = validFrom;
+    outTable->validTo = validTo;
+
+    // Vector of independent index values. Filled by table read.
+    outTable->index = NULL;
+
+    // Array of dependent table values corresponding to index values. Filled by table read.
+    outTable->values = NULL;
+
+    return outTable;
+}
+
+psLookupTable* psLookupTableRead(psLookupTable *table)
+{
+    bool typeLine = true;
+    char *line = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *linePtr = NULL;
+    psParseErrorType status = PS_PARSE_SUCCESS;
+    psU64 lineCount = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psU64 failedLines = 0;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(table->fileName,NULL);
+    if((fp=fopen(table->fileName, "r")) == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_FILE_NOT_FOUND, table->fileName);
+        return table;
+    }
+
+    indexVec = table->index;
+    table->values = psArrayAlloc(1);
+    values = table->values;
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // Loop through file to get numRows, numCols, and column data types
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            if(typeLine == true) {
+
+                // Determine column types from first line in data file after comments
+                while((strType=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+                    typeLine = false;
+                    if(!strncmp(strType, "psU8", 4)) {
+                        elemType = PS_TYPE_U8;
+                    } else if(!strncmp(strType, "psS8", 4)) {
+                        elemType = PS_TYPE_S8;
+                    } else if(!strncmp(strType, "psU16", 5)) {
+                        elemType = PS_TYPE_U16;
+                    } else if(!strncmp(strType, "psS16", 5)) {
+                        elemType = PS_TYPE_S16;
+                    } else if(!strncmp(strType, "psU32", 5)) {
+                        elemType = PS_TYPE_U32;
+                    } else if(!strncmp(strType, "psS32", 5)) {
+                        elemType = PS_TYPE_S32;
+                    } else if(!strncmp(strType, "psU64", 5)) {
+                        elemType = PS_TYPE_U64;
+                    } else if(!strncmp(strType, "psS64", 5)) {
+                        elemType = PS_TYPE_S64;
+                    } else if(!strncmp(strType, "psF32", 5)) {
+                        elemType = PS_TYPE_F32;
+                    } else if(!strncmp(strType, "psF64", 5)) {
+                        elemType = PS_TYPE_F64;
+                    } else {
+                        status = PS_PARSE_ERROR_TYPE;
+                    }
+
+                    // Realloc number of columns as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorAlloc(0, elemType);
+                    } else {
+                        values = psArrayRealloc(values, numCols-1);
+                        values->n = values->nalloc;
+                        values->data[numCols-2] = psVectorAlloc(0, elemType);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strType);
+                }
+            } else {
+
+                // Parse and add values to all columns
+                numRows++;
+                numCols = 0;
+                while((strValue=getToken(&linePtr, " ", &status)) != NULL) {
+                    numCols++;
+
+                    // Realloc number of rows as you go
+                    if(numCols == 1) {
+                        indexVec = psVectorRecycle(indexVec, numRows, indexVec->type.type);
+                        parseValue(indexVec, numRows-1, strValue, &status);
+                    } else {
+                        valuesVec = values->data[numCols-2];
+                        valuesVec = psVectorRecycle(valuesVec, numRows, valuesVec->type.type);
+                        parseValue(valuesVec, numRows-1, strValue, &status);
+                    }
+
+                    if(status) {
+                        status = printError(lineCount, strValue, status);
+                        failedLines++;
+                    }
+                    psFree(strValue);
+                } // end while
+            } // end else
+        } // if ignoreLine
+    } // end while
+
+    psFree(line);
+
+    // Set table for return
+    table->numRows = numRows;
+    table->numCols = numCols-1;
+    table->index = indexVec;
+    table->values = values;
+
+    fclose(fp);
+
+    return table;
+}
+
+psF64 psLookupTableInterpolate(psLookupTable *table, psF64 index, psU64 column, psLookupStatusType *status)
+{
+    psU64 hiIdx = 0;
+    psU64 loIdx = 0;
+    psU64 numRows = 0;
+    psU64 numCols = 0;
+    psF64 out = 0.0;
+    psF64 denom = 0.0;
+    psVector *indexVec = NULL;
+    psVector *valuesVec = NULL;
+    psArray *values = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,0.0);
+    indexVec = table->index;
+    values = table->values;
+    numRows = table->numRows;
+    numCols = table->numCols;
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+    PS_PTR_CHECK_NULL(values,0.0);
+    PS_INT_CHECK_EQUALS(numRows, 0,0.0);
+    PS_INT_CHECK_EQUALS(numCols, 0,0.0);
+    PS_INT_CHECK_RANGE(column, 0, numCols-1, 0.0);
+
+
+    valuesVec = (psVector*)values->data[column];
+    PS_PTR_CHECK_NULL(indexVec,0.0);
+
+    if(index<indexVec->data.F64[0] || index<table->validFrom) {
+
+        // Index value past top of table
+        *status = PS_LOOKUP_PAST_TOP;
+        return valuesVec->data.F64[0];
+    } else if(index>indexVec->data.F64[numRows-1] || index>table->validTo) {
+
+        // Index value past bottom of table
+        *status = PS_LOOKUP_PAST_BOTTOM;
+        return valuesVec->data.F64[numRows-1];
+    } else {
+
+        // Interpolation
+        while(index > indexVec->data.F64[hiIdx]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH, hiIdx);
+                *status = PS_LOOKUP_ERROR;
+                return 0.0;
+            }
+        }
+
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW, loIdx);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        }
+
+        denom = indexVec->data.F64[hiIdx] - indexVec->data.F64[loIdx];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO);
+            *status = PS_LOOKUP_ERROR;
+            return 0.0;
+        } else {
+            out = valuesVec->data.F64[loIdx]+(valuesVec->data.F64[hiIdx]-valuesVec->data.F64[loIdx])
+                  *(index-indexVec->data.F64[loIdx])/denom;
+        }
+    }
+
+    return out;
+}
+
+psVector* psLookupTableInterpolateAll(psLookupTable *table, psF64 index, psVector *stats)
+{
+    psU64 i = 0;
+    psU64 numCols = 0;
+    psVector *outVector = NULL;
+    psLookupStatusType status = PS_LOOKUP_SUCCESS;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(table,NULL);
+    PS_PTR_CHECK_NULL(stats,NULL);
+    numCols = table->numCols;
+    PS_INT_CHECK_EQUALS(numCols, 0,NULL);
+
+    outVector = psVectorAlloc(numCols, PS_TYPE_F64);
+
+    // Fill vectors with results and status of results
+    for(i=0; i<numCols; i++) {
+        outVector->data.F64[i] = psLookupTableInterpolate(table, index, i, &status);
+        stats->data.U32[i] = status;
+    }
+
+    return outVector;
+}
+
Index: /branches/rel4/psLib/src/types/psLookupTable.h
===================================================================
--- /branches/rel4/psLib/src/types/psLookupTable.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psLookupTable.h	(revision 3057)
@@ -0,0 +1,112 @@
+/** @file  psLookupTable.h
+*
+*  @brief This file defines the structure and functions for table lookups.
+*
+*  @ingroup fileUtils
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-11-09 00:38:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_LOOKUPTABLE_H
+#define PS_LOOKUPTABLE_H
+
+#include "psType.h"
+#include "psVector.h"
+#include "psArray.h"
+
+
+/** Lookup table structure
+ *
+ *  Holds table data read from external data files.
+ *
+ */
+typedef struct
+{
+    const char *fileName;              ///< Name of file with table
+    psU64 numRows;                     ///< Number of table rows
+    psU64 numCols;                     ///< Number of table columns
+    psF64 validFrom;                   ///< Lower bound for rable read
+    psF64 validTo;                     ///< Upper bound for table read
+    psVector *index;                   ///< Vector of independent index values
+    psArray *values;                   ///< Array of dependent table values corresponding to index values
+}
+psLookupTable;
+
+
+/** Lookup table lookup status and error conditions
+ *
+ *  Success, failure, and status conditions for table lookups.
+ */
+typedef enum {
+    PS_LOOKUP_SUCCESS             = 0x0000,        ///< Table lookup succeeded
+    PS_LOOKUP_PAST_TOP            = 0x0101,        ///< Lookup off top of table
+    PS_LOOKUP_PAST_BOTTOM         = 0x0102,        ///< Lookup off bottom of table
+    PS_LOOKUP_ERROR               = 0x0104         ///< Any other type of lookup error
+} psLookupStatusType;
+
+/** Lookup table parse status and error conditions
+ *
+ *  Success, failure, and status conditions for table parsing.
+ */
+typedef enum {
+    PS_PARSE_SUCCESS              = 0x0000,        ///< Table lookup succeeded
+    PS_PARSE_ERROR_TYPE           = 0x0101,        ///< Error parsing type
+    PS_PARSE_ERROR_VALUE          = 0x0102,        ///< Error parsing numerical value
+    PS_PARSE_ERROR_GENERAL        = 0x0104         ///< Any other type of lookup error
+}psParseErrorType;
+
+/** Allocator for psLookupTable struct
+ *
+ *  Allocates a new psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableAlloc(
+    const char *fileName,           ///< Name of file to read
+    psF64 validFrom,                ///< Lower bound for rable read
+    psF64 validTo                   ///< Upper bound for table read
+);
+
+/** Read lookup table
+ *
+ *  Reads a lookup table and fills corresponding psLookupTable struct.
+ *
+ *  @return psLookupTable*     New psLookupTable struct.
+ */
+psLookupTable* psLookupTableRead(
+    psLookupTable *table            ///< Table to read
+);
+
+/** Lookup and interpolate value from table.
+ *
+ *  Interpolates value from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psF64 psLookupTableInterpolate(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psU64 column,                   ///< Column in table to be interpolated
+    psLookupStatusType *status      ///< Status of lookup
+);
+
+/** Lookup and interpolate all values from table.
+ *
+ *  Interpolates all values from table. Sets status bit for success or one of several possible failure
+ *  conditions.
+ *
+ *  @return psLookupTable*     New psLookupTable struct
+ */
+psVector* psLookupTableInterpolateAll(
+    psLookupTable *table,           ///< Table with data
+    psF64 index,                    ///< Value to be interpolated
+    psVector *stats                 ///< Vector of status for each lookup
+);
+
+#endif
Index: /branches/rel4/psLib/src/types/psMetadata.c
===================================================================
--- /branches/rel4/psLib/src/types/psMetadata.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psMetadata.c	(revision 3057)
@@ -0,0 +1,513 @@
+
+/** @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.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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 "psLookupTable.h"
+#include "psString.h"
+#include "psAstronomyErrors.h"
+#include "psConstants.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static psS32 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);
+    if (type != PS_META_PRIMITIVE) {
+        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, psElemType pType, 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, pType, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psElemType pType, psMetadataType type,
+                                     const char *comment, va_list argPtr)
+{
+    psMetadataItem* metadataItem = NULL;
+
+
+    PS_PTR_CHECK_NULL(name,NULL);
+
+    // Allocate metadata item
+    metadataItem = (psMetadataItem*) psAlloc(sizeof(psMetadataItem));
+    metadataItem->data.V = NULL;
+
+    // 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
+    *(psS32 *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+    metadataItem->pType = pType;
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Set metadata item value
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            metadataItem->data.B = (psBool)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_S32:
+            metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+            break;
+        case PS_TYPE_F32:
+            metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+            break;
+        case PS_TYPE_F64:
+            metadataItem->data.F64 = (psF64)va_arg(argPtr, psF64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+            psFree(metadataItem);
+            metadataItem = NULL;
+        }
+        break;
+    case PS_META_STR:
+        // Perform copy of input strings
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_LIST:
+    case PS_META_VEC:
+    case PS_META_HASH:
+    case PS_META_LOOKUPTABLE:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        // Copy of input data not performed due to variability of data types
+        metadataItem->data.V = va_arg(argPtr, psPtr);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, type);
+        psFree(metadataItem);
+        metadataItem = 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;
+}
+
+psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location)
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+    PS_PTR_CHECK_NULL(metadataItem,NULL);
+    PS_PTR_CHECK_NULL(metadataItem->name,NULL);
+
+    newType = metadataItem->type;
+    mdTable = md->table;
+    mdList = md->list;
+    key = metadataItem->name;
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_LIST) {
+
+            if(existingEntry->data.list == NULL) {
+                existingEntry->data.list = psListAlloc(NULL);
+            }
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED, metadataItem->name);
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_LIST && newType!= PS_META_LIST) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_TYPE_PTR, PS_META_LIST, NULL, NULL);
+            newFolderEntry->data.list = psListAlloc(NULL);
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->data.list, PS_LIST_TAIL, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false, PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,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(metadataItem->data.list == NULL) {
+                metadataItem->data.list = psListAlloc(NULL);
+            }
+
+            if(!psListAdd(metadataItem->data.list, PS_LIST_TAIL, existingEntry)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED,key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED,key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_LIST metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_LIST) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name, psElemType pType,
+                     psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, pType, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_FAILED);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key)
+{
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    mdList = md->list;
+    mdTable = md->table;
+
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem*)psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_FAILED, key);
+            return false;
+        }
+
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+            return false;
+        }
+
+        key = entry->name;
+        if(key == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED, where);
+            return false;
+        }
+    }
+
+    if (!psListRemoveData(mdList, entry)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
+        return false;
+    }
+
+    // Remove entry from metadata collection's table
+    if (!psHashRemove(mdTable, key)) {
+        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
+        return false;
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata *md, const char *key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->table,NULL);
+    PS_PTR_CHECK_NULL(key,NULL);
+
+    mdTable = md->table;
+    entry = (psMetadataItem*)psHashLookup(mdTable, key);
+
+    return entry;
+}
+
+void* psMetadataLookupPtr(psMetadata *md, const char *key, psBool *status)
+{
+    psMetadataItem *metadataItem = NULL;
+
+    if (status) {
+        *status = true;
+    }
+
+    metadataItem = psMetadataLookup(md, key);
+    if(metadataItem == NULL) {
+        if (status) {
+            *status = false;
+        }
+        return NULL;
+    }
+
+    if(metadataItem->type == PS_META_PRIMITIVE && metadataItem->pType != PS_TYPE_PTR) {
+        if (status) {
+            *status = false;
+        }
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH,
+                metadataItem->pType,
+                PS_TYPE_PTR);
+        return NULL;
+    } else {
+        return metadataItem->data.V;
+    }
+}
+
+#define psMetadataLookupNumTYPE(TYPE) \
+ps##TYPE psMetadataLookup##TYPE(psMetadata *md, const char *key, psBool *status) \
+{ \
+    psMetadataItem *metadataItem = NULL; \
+    \
+    if (status) { \
+        *status = true; \
+    } \
+    \
+    metadataItem = psMetadataLookup(md, key); \
+    if(metadataItem == NULL) { \
+        if (status) { \
+            *status = false; \
+        } \
+        return 0; \
+    } \
+    \
+    if (metadataItem->type == PS_META_PRIMITIVE) { \
+        switch (metadataItem->pType) { \
+        case PS_TYPE_S32: \
+            return metadataItem->data.S32; \
+        case PS_TYPE_F32: \
+            return metadataItem->data.F32; \
+        case PS_TYPE_F64: \
+            return metadataItem->data.F64; \
+        case PS_TYPE_BOOL: \
+            if (metadataItem->data.B) { \
+                return 1; \
+            } \
+            return 0; \
+        default: \
+            break; \
+        } \
+    } \
+    \
+    /* if you get to this point, the value is not a number. */ \
+    if (status) { \
+        *status = false; \
+    } \
+    \
+    return 0; \
+}
+
+psMetadataLookupNumTYPE(F32)
+psMetadataLookupNumTYPE(F64)
+psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
+
+psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
+{
+    psMetadataItem* entry = NULL;
+
+    PS_PTR_CHECK_NULL(md,NULL);
+    PS_PTR_CHECK_NULL(md->list,NULL);
+
+    entry = (psMetadataItem*) psListGet(md->list, where);
+    if (entry == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED, where);
+        return NULL;
+    }
+
+    return entry;
+}
Index: /branches/rel4/psLib/src/types/psMetadata.h
===================================================================
--- /branches/rel4/psLib/src/types/psMetadata.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psMetadata.h	(revision 3057)
@@ -0,0 +1,284 @@
+
+/** @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.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
+*
+*  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_PRIMITIVE,                 ///< Primitive data.
+    PS_META_LIST,                      ///< List data (Stored as item.data.list).
+    PS_META_STR,                       ///< String data (Stored as item.data.V).
+    PS_META_VEC,                       ///< Vector data (Stored as item.data.V).
+    PS_META_IMG,                       ///< Image data (Stored as item.data.V).
+    PS_META_HASH,                      ///< Hash data (Stored as item.data.V).
+    PS_META_LOOKUPTABLE,               ///< Lookup table data (Stored as item.data.V).
+    PS_META_JPEG,                      ///< JPEG data (Stored as item.data.V).
+    PS_META_PNG,                       ///< PNG data (Stored as item.data.V).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored as item.data.V).
+    PS_META_UNKNOWN,                   ///< Other data (Stored as item.data.V).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** 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*  list;                     ///< Metadata in linked-list
+    psHash*  table;                    ///< Metadata in a hash table
+}
+psMetadata;
+
+/** 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 psS32 id;                    ///< Unique ID for metadata item.
+    char *name;                        ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    psElemType pType;                  ///< Primitive data type
+    union {
+        psBool B;                      ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psList *list;                  ///< List data.
+        psMetadata *md;                ///< Metadata data.
+        psPtr V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+}
+psMetadataItem;
+
+/** 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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+    psElemType pType,                  ///< Primitive type.
+    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.
+ */
+psBool psMetadataAddItem(
+    psMetadata*  md,          ///< Metadata collection to insert metadat item.
+    psMetadataItem*  item,    ///< Metadata item to be added.
+    psS32 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.
+ */
+psBool psMetadataAdd(
+    psMetadata* md,           ///< Metadata collection to insert metadat item.
+    psS32 where,              ///< Location to be added.
+    const char *name,         ///< Name of metadata item.
+    psElemType pType,         ///< Primitive type.
+    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.
+ */
+psBool psMetadataRemove(
+    psMetadata*  md,           ///< Metadata collection to remove metadata item.
+    psS32 where,               ///< Location to be removed.
+    const char * 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 * md,           ///< Metadata collection to lookup metadata item.
+    const char * key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name and return its double precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF64 : Value of metadata item.
+ */
+psF64 psMetadataLookupF64(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its single precision value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psF32 : Value of metadata item.
+ */
+psF32 psMetadataLookupF32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psS32 : Value of metadata item.
+ */
+psS32 psMetadataLookupS32(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** Find an item in the metadata collection based on key name and return its integer value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return void* : Value of metadata item.
+ */
+void* psMetadataLookupPtr(
+    psMetadata* md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
+/** 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*  md,           ///< Metadata collection to insert metadat item.
+    psS32 where                ///< Location to be retrieved.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/types/psMetadataConfig.c
===================================================================
--- /branches/rel4/psLib/src/types/psMetadataConfig.c	(revision 3057)
+++ /branches/rel4/psLib/src/types/psMetadataConfig.c	(revision 3057)
@@ -0,0 +1,1127 @@
+/** @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.18 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 20:48:59 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <libxml/parser.h>
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.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"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR)                                                                          \
+fits_get_errstatus(status, fitsErr);                                                                         \
+psError(PS_ERR_IO,true, STRING, PS_ERROR, fitsErr);                                                          \
+status = 0;                                                                                                  \
+fits_close_file(fd, &status);                                                                                \
+if(status){                                                                                                  \
+    fits_get_errstatus(status, fitsErr);                                                                     \
+    psError(PS_ERR_IO,true, "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;                                                                                       \
+}
+
+/** 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                                          */
+/*****************************************************************************/
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName);
+static void p_psInitVectorXml(void *ctx, char *tagName);
+static void p_psInitMetadataItemXml(void *ctx, char *tagName);
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+psBool 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, psS32 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. */
+psS32 repeatedChars(char *inString, char ch)
+{
+    psS32 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, psS32 *status)
+{
+    char *cleanToken = NULL;
+    psS32 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, psS32 *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. */
+psBool parseBool(char *inString, psS32 *status)
+{
+    psBool 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, psS32 *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    psS32 i = 0;
+    psS32 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(PS_ERR_BAD_PARAMETER_VALUE,true,
+                        PS_ERRORTEXT_psMetadataIO_TYPE_INVALID,
+                        elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+    psElemType pType;
+    psBool success = true;
+
+    PS_PTR_CHECK_NULL(fd, success);
+    PS_PTR_CHECK_NULL(format, success);
+    PS_PTR_CHECK_NULL(metadataItem, success);
+
+    type = metadataItem->type;
+    pType = metadataItem->pType;
+
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            fprintf(fd, format, metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            fprintf(fd,format, metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            fprintf(fd, format, metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            fprintf(fd, format, metadataItem->data.F64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)pType);
+            success = false;
+        }
+        break;
+    case PS_META_STR:
+        fprintf(fd,format, (char*)metadataItem->data.V);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)type);
+        success = false;
+    }
+
+    return success;
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, psS32 extNum, char *fileName)
+{
+    psBool tempBool;
+    psBool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    psS32 i;
+    psS32 hduType = 0;
+    psS32 status = 0;
+    psS32 numKeys = 0;
+    psS32 keyNum = 0;
+    fitsfile *fd = NULL;
+
+    PS_PTR_CHECK_NULL(fileName,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 < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE,
+                extNum);
+        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':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_S32, PS_META_PRIMITIVE,
+                                    keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_F64, PS_META_PRIMITIVE,
+                                    keyComment, atof(keyValue));
+            break;
+        case 'C':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_PTR, PS_META_STR, keyComment,
+                                    keyValue);
+            break;
+        case 'L':
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_BOOL, PS_META_PRIMITIVE, keyComment,
+                                    tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID, keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadataIO_ADD_FAILED, keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    psBool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    psS32 status = 0;
+    psU32 lineCount = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType pType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    PS_PTR_CHECK_NULL(fileName,NULL);
+    if((fp=fopen(fileName, "r")) == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // 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) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount,
+                        fileName);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_LIST;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_BOOL;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F64;
+            } else {
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
+                        fileName);
+                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_LIST) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    (*nFail)++;
+                    status = 0;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
+                            fileName);
+                    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) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount,
+                        fileName);
+                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_LIST) {
+                    if(overwrite) {
+                        psMetadataRemove(md, INT_MIN, strName);
+                    } else {
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
+                                fileName);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_LIST:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+                break;
+            case PS_META_STR:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, pType, &status);
+                if(!status) {
+                    psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                            strType, lineCount, fileName);
+                    continue;
+                }
+                break;
+            case PS_META_PRIMITIVE:
+                switch (pType) {
+                case PS_TYPE_BOOL:
+                    tempBool = parseBool(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempBool);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_S32:
+                    tempInt = (psS32)parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempInt);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_F32:
+                case PS_TYPE_F64:
+                    tempDbl = parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempDbl);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true,
+                                PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount,
+                                fileName);
+                        continue;
+                    }
+                    break;
+                default:
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                            fileName);
+                    continue;
+                } // switch
+                break;
+            default:
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                        fileName);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return md;
+}
+
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)
+{
+    psU64 i = 0;
+    char* psTagName = NULL;
+    char *psAttName = NULL;
+    char *psAttValue = NULL;
+    const xmlChar *attName = NULL;
+    const xmlChar *attValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psTagName = psStringCopy(tagName);
+
+    // Metadata containter for housing element attributes used by other SAX events
+    htAtts = psHashAlloc(10);
+
+    // Get tag name
+    if(psTagName != NULL) {
+        psHashAdd(htAtts, "tagName", psTagName);
+    } else {
+        PS_PTR_CHECK_NULL_GENERAL(psTagName, return);
+        psFree(htAtts);
+        psFree(psTagName);
+        return;
+    }
+
+    // Get all attribute names and attribute values
+    if(atts != NULL) {
+        attName = atts[i++];
+        attValue = atts[i++];
+        while(attName != NULL) {
+            if(attValue != NULL) {
+
+                // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+                psAttName = psStringCopy(attName);
+                psAttValue = psStringCopy(attValue);
+                psHashAdd(htAtts, psAttName, psAttValue);
+                psFree(psAttName);
+                psFree(psAttValue);
+            } else {
+                PS_PTR_CHECK_NULL_GENERAL(psAttValue, return);
+                psFree(htAtts);
+                psFree(psTagName);
+                return;
+            }
+            attName = atts[i++];
+            attValue = atts[i++];
+        }
+    }
+
+    // Add attributes to metadata
+    psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_TYPE_PTR, PS_META_HASH, NULL, htAtts);
+
+    psFree(psTagName);
+
+    return;
+}
+
+static void p_psInitMetadataItemXml(void *ctx, char *tagName)
+{
+    psBool overwrite = false;
+    psBool tempBool = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *fileName = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *metadataItem = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    metadataItem = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem, return);
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem->data.list, return);
+    metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)metadataItem->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    // Get attribute value, if there is one
+    strValue = psHashLookup(htAtts, "value");
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    lineNumber, fileName);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Create metadata item and add to metadata
+    switch(mdType) {
+    case PS_META_LIST:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+        break;
+    case PS_META_STR:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, strValue);
+        break;
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            tempBool = parseBool((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempBool);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_S32:
+            tempInt = (psS32)parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempInt);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_F32:
+        case PS_TYPE_F64:
+            tempDbl = parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempDbl);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+        } // End switch
+        break;
+    default:
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+    } // End switch
+
+
+    return;
+}
+
+
+static void p_psInitVectorXml(void *ctx, char *tagName)
+{
+    bool overwrite = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *fileName = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psVector *vec = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    strValue = psHashLookup(htAtts, "value");
+    PS_PTR_CHECK_NULL_GENERAL(strValue, return);
+
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    input->line, input->filename);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Get value
+    vec = parseVector((char*)strValue, pType, &status);
+    if(!status) {
+        psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, NULL, vec);
+    } else {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                lineNumber, fileName);
+    }
+    psFree(vec);
+}
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName)
+{
+    char *psStartTagName = NULL;
+    char *psEndTagName = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psEndTagName = psStringCopy(tagName);
+
+    // Compare start and end tag names
+    psStartTagName = psHashLookup(htAtts, "tagName");
+    PS_PTR_CHECK_NULL_GENERAL(psStartTagName, return);
+    if(strcmp(psEndTagName, psStartTagName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName);
+    }
+
+    // Initialize psLib structs
+    if(!strcmp(psEndTagName, "psMetadataItem")) {
+        p_psInitMetadataItemXml(ctx, psEndTagName);
+    } else if(!strcmp(psEndTagName, "psVector")) {
+        p_psInitVectorXml(ctx, psEndTagName);
+    } else if(strcmp(psEndTagName, "psRoot")) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName);
+    }
+
+    // Free temporary metadata item and its hash table
+    psListRemove(tables->data.list, PS_LIST_TAIL);
+
+    psFree(psEndTagName);
+
+    return;
+}
+
+psMetadata*  psMetadataParseConfigXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    xmlSAXHandler saxHandler;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(fileName, NULL);
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Sax handler initializations
+    saxHandler.internalSubset           = NULL;
+    saxHandler.isStandalone             = NULL;
+    saxHandler.hasInternalSubset        = NULL;
+    saxHandler.hasExternalSubset        = NULL;
+    saxHandler.resolveEntity            = NULL;
+    saxHandler.getEntity                = NULL;
+    saxHandler.entityDecl               = NULL;
+    saxHandler.notationDecl             = NULL;
+    saxHandler.attributeDecl            = NULL;
+    saxHandler.elementDecl              = NULL;
+    saxHandler.unparsedEntityDecl       = NULL;
+    saxHandler.setDocumentLocator       = NULL;
+    saxHandler.startDocument            = NULL;
+    saxHandler.endDocument              = NULL;
+    saxHandler.startElement             = p_saxStartElement;
+    saxHandler.endElement               = p_saxEndElement;
+    saxHandler.reference                = NULL;
+    saxHandler.characters               = NULL;
+    saxHandler.ignorableWhitespace      = NULL;
+    saxHandler.processingInstruction    = NULL;
+    saxHandler.comment                  = NULL;
+    saxHandler.warning                  = xmlParserError;
+    saxHandler.error                    = xmlParserError;
+    saxHandler.fatalError               = xmlParserError;
+    saxHandler.getParameterEntity       = NULL;
+    saxHandler.cdataBlock               = NULL;
+    saxHandler.externalSubset           = NULL;
+    saxHandler.initialized              = 1;
+    saxHandler._private                 = md;
+    saxHandler.startElementNs           = NULL;
+    saxHandler.endElementNs             = NULL;
+    saxHandler.serror                   = NULL;
+
+    // Parse XML file
+    if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Parser and memory cleanups for libxml2
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return md;
+}
Index: /branches/rel4/psLib/src/types/psMetadataConfig.h
===================================================================
--- /branches/rel4/psLib/src/types/psMetadataConfig.h	(revision 3057)
+++ /branches/rel4/psLib/src/types/psMetadataConfig.h	(revision 3057)
@@ -0,0 +1,85 @@
+/** @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.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-06 20:00:03 $
+*
+*  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.
+ */
+bool psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* 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.
+    psS32 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 psMetadata* : Resulting metadata from read.
+ */
+psMetadata* psMetadataParseConfig(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/** Read XML metadata configuration file.
+ *
+ *  Loads pre-defined XML settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return psMetadata* : Resulting metadata from read.
+ */
+
+psMetadata*  psMetadataParseConfigXml(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/src/xml/psXML.c
===================================================================
--- /branches/rel4/psLib/src/xml/psXML.c	(revision 3057)
+++ /branches/rel4/psLib/src/xml/psXML.c	(revision 3057)
@@ -0,0 +1,1127 @@
+/** @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.18 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 20:48:59 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <libxml/parser.h>
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.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"
+#include "psConstants.h"
+#include "psAstronomyErrors.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR)                                                                          \
+fits_get_errstatus(status, fitsErr);                                                                         \
+psError(PS_ERR_IO,true, STRING, PS_ERROR, fitsErr);                                                          \
+status = 0;                                                                                                  \
+fits_close_file(fd, &status);                                                                                \
+if(status){                                                                                                  \
+    fits_get_errstatus(status, fitsErr);                                                                     \
+    psError(PS_ERR_IO,true, "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;                                                                                       \
+}
+
+/** 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                                          */
+/*****************************************************************************/
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName);
+static void p_psInitVectorXml(void *ctx, char *tagName);
+static void p_psInitMetadataItemXml(void *ctx, char *tagName);
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts);
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+psBool 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, psS32 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. */
+psS32 repeatedChars(char *inString, char ch)
+{
+    psS32 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, psS32 *status)
+{
+    char *cleanToken = NULL;
+    psS32 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, psS32 *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. */
+psBool parseBool(char *inString, psS32 *status)
+{
+    psBool 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, psS32 *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    psS32 i = 0;
+    psS32 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(PS_ERR_BAD_PARAMETER_VALUE,true,
+                        PS_ERRORTEXT_psMetadataIO_TYPE_INVALID,
+                        elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+    psElemType pType;
+    psBool success = true;
+
+    PS_PTR_CHECK_NULL(fd, success);
+    PS_PTR_CHECK_NULL(format, success);
+    PS_PTR_CHECK_NULL(metadataItem, success);
+
+    type = metadataItem->type;
+    pType = metadataItem->pType;
+
+    switch(type) {
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            fprintf(fd, format, metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            fprintf(fd,format, metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            fprintf(fd, format, metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            fprintf(fd, format, metadataItem->data.F64);
+            break;
+        default:
+            psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)pType);
+            success = false;
+        }
+        break;
+    case PS_META_STR:
+        fprintf(fd,format, (char*)metadataItem->data.V);
+        break;
+    default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE,true, PS_ERRORTEXT_psMetadata_METATYPE_INVALID, (int)type);
+        success = false;
+    }
+
+    return success;
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, psS32 extNum, char *fileName)
+{
+    psBool tempBool;
+    psBool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    psS32 i;
+    psS32 hduType = 0;
+    psS32 status = 0;
+    psS32 numKeys = 0;
+    psS32 keyNum = 0;
+    fitsfile *fd = NULL;
+
+    PS_PTR_CHECK_NULL(fileName,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 < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE,
+                extNum);
+        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':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_S32, PS_META_PRIMITIVE,
+                                    keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_F64, PS_META_PRIMITIVE,
+                                    keyComment, atof(keyValue));
+            break;
+        case 'C':
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_PTR, PS_META_STR, keyComment,
+                                    keyValue);
+            break;
+        case 'L':
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, PS_TYPE_BOOL, PS_META_PRIMITIVE, keyComment,
+                                    tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID, keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadataIO_ADD_FAILED, keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    psBool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    psS32 status = 0;
+    psU32 lineCount = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType pType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    PS_PTR_CHECK_NULL(fileName,NULL);
+    if((fp=fopen(fileName, "r")) == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+
+    // 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) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                (*nFail)++;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true,
+                        PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount,
+                        fileName);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_LIST;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                pType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_BOOL;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_PRIMITIVE;
+                pType = PS_TYPE_F64;
+            } else {
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount,
+                        fileName);
+                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_LIST) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    (*nFail)++;
+                    status = 0;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount,
+                            fileName);
+                    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) {
+                (*nFail)++;
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount,
+                        fileName);
+                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_LIST) {
+                    if(overwrite) {
+                        psMetadataRemove(md, INT_MIN, strName);
+                    } else {
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount,
+                                fileName);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_LIST:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+                break;
+            case PS_META_STR:
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, pType, &status);
+                if(!status) {
+                    psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                            strType, lineCount, fileName);
+                    continue;
+                }
+                break;
+            case PS_META_PRIMITIVE:
+                switch (pType) {
+                case PS_TYPE_BOOL:
+                    tempBool = parseBool(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempBool);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_S32:
+                    tempInt = (psS32)parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempInt);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName,
+                                strType, lineCount, fileName);
+                        continue;
+                    }
+                    break;
+                case PS_TYPE_F32:
+                case PS_TYPE_F64:
+                    tempDbl = parseValue(strValue, &status);
+                    if(!status) {
+                        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, strComment, tempDbl);
+                    } else {
+                        status = 0;
+                        (*nFail)++;
+                        psError(PS_ERR_IO, true,
+                                PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount,
+                                fileName);
+                        continue;
+                    }
+                    break;
+                default:
+                    (*nFail)++;
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                            fileName);
+                    continue;
+                } // switch
+                break;
+            default:
+                (*nFail)++;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount,
+                        fileName);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return md;
+}
+
+static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)
+{
+    psU64 i = 0;
+    char* psTagName = NULL;
+    char *psAttName = NULL;
+    char *psAttValue = NULL;
+    const xmlChar *attName = NULL;
+    const xmlChar *attValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psTagName = psStringCopy(tagName);
+
+    // Metadata containter for housing element attributes used by other SAX events
+    htAtts = psHashAlloc(10);
+
+    // Get tag name
+    if(psTagName != NULL) {
+        psHashAdd(htAtts, "tagName", psTagName);
+    } else {
+        PS_PTR_CHECK_NULL_GENERAL(psTagName, return);
+        psFree(htAtts);
+        psFree(psTagName);
+        return;
+    }
+
+    // Get all attribute names and attribute values
+    if(atts != NULL) {
+        attName = atts[i++];
+        attValue = atts[i++];
+        while(attName != NULL) {
+            if(attValue != NULL) {
+
+                // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+                psAttName = psStringCopy(attName);
+                psAttValue = psStringCopy(attValue);
+                psHashAdd(htAtts, psAttName, psAttValue);
+                psFree(psAttName);
+                psFree(psAttValue);
+            } else {
+                PS_PTR_CHECK_NULL_GENERAL(psAttValue, return);
+                psFree(htAtts);
+                psFree(psTagName);
+                return;
+            }
+            attName = atts[i++];
+            attValue = atts[i++];
+        }
+    }
+
+    // Add attributes to metadata
+    psMetadataAdd(md, PS_LIST_TAIL, "htAtts", PS_TYPE_PTR, PS_META_HASH, NULL, htAtts);
+
+    psFree(psTagName);
+
+    return;
+}
+
+static void p_psInitMetadataItemXml(void *ctx, char *tagName)
+{
+    psBool overwrite = false;
+    psBool tempBool = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *fileName = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *metadataItem = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    metadataItem = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem, return);
+    PS_PTR_CHECK_NULL_GENERAL(metadataItem->data.list, return);
+    metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)metadataItem->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strType, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    // Get attribute value, if there is one
+    strValue = psHashLookup(htAtts, "value");
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    lineNumber, fileName);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Create metadata item and add to metadata
+    switch(mdType) {
+    case PS_META_LIST:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, NULL);
+        break;
+    case PS_META_STR:
+        psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, strValue);
+        break;
+    case PS_META_PRIMITIVE:
+        switch(pType) {
+        case PS_TYPE_BOOL:
+            tempBool = parseBool((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempBool);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_S32:
+            tempInt = (psS32)parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempInt);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        case PS_TYPE_F32:
+        case PS_TYPE_F64:
+            tempDbl = parseValue((char*)strValue, &status);
+            if(!status) {
+                psMetadataAdd(md, PS_LIST_TAIL, strName, pType, mdType, NULL, tempDbl);
+            } else {
+                status = 0;
+                psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                        lineNumber, fileName);
+            }
+            break;
+        default:
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+        } // End switch
+        break;
+    default:
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineNumber, fileName);
+    } // End switch
+
+
+    return;
+}
+
+
+static void p_psInitVectorXml(void *ctx, char *tagName)
+{
+    bool overwrite = false;
+    psS32 status = 0;
+    psU32 lineNumber = 0;
+    psElemType pType;
+    psMetadataType mdType;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *fileName = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    psMetadataItem *metadataItem = NULL;
+    psVector *vec = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+    fileName = (char*)input->filename;
+    PS_PTR_CHECK_NULL_GENERAL(fileName, return);
+    lineNumber = input->line;
+
+    // Get attribute name
+    strName = psHashLookup(htAtts, "name");
+    if(strName == NULL) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_NO_NAME, lineNumber, fileName);
+        return;
+    }
+
+    // Get attribute type, if there is one
+    strType = psHashLookup(htAtts, "psType");
+    if(strType!= NULL) {
+        if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psString")) {
+            mdType = PS_META_STR;
+            pType = PS_TYPE_PTR;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psBool")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_U8;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psS32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_S32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF32")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F32;
+        } else if(xmlStrEqual(BAD_CAST strType, BAD_CAST "psF64")) {
+            mdType = PS_META_PRIMITIVE;
+            pType = PS_TYPE_F64;
+        } else {
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE, strName, lineNumber,
+                    fileName);
+            return;
+        }
+    }
+
+    strValue = psHashLookup(htAtts, "value");
+    PS_PTR_CHECK_NULL_GENERAL(strValue, return);
+
+
+    /* If metadata item is found, and 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, "overwrite");
+    if(metadataItem != NULL) {
+        overwrite = parseBool((char*)strValue, &status);
+        if(status) {
+            status = 0;
+            psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                    input->line, input->filename);
+        }
+        metadataItem = psMetadataLookup(md, strName);
+        if(metadataItem != NULL) {
+            if(metadataItem->type != PS_META_LIST) {
+                if(overwrite) {
+                    psMetadataRemove(md, INT_MIN, strName);
+                } else {
+                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
+                            fileName);
+                    return;
+                }
+            }
+        }
+    }
+
+    // Get value
+    vec = parseVector((char*)strValue, pType, &status);
+    if(!status) {
+        psMetadataAdd(md, PS_LIST_TAIL, strName+1, pType, mdType, NULL, vec);
+    } else {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType,
+                lineNumber, fileName);
+    }
+    psFree(vec);
+}
+
+static void p_saxEndElement(void *ctx, const xmlChar *tagName)
+{
+    char *psStartTagName = NULL;
+    char *psEndTagName = NULL;
+    psMetadata* md = NULL;
+    psHash* htAtts = NULL;
+    psMetadataItem *table = NULL;
+    psMetadataItem *tables = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+    xmlParserInputPtr input = NULL;
+
+
+    // Get and check initial data pointers
+    ctxt = (xmlParserCtxtPtr)ctx;
+    PS_PTR_CHECK_NULL_GENERAL(ctxt, return);
+    md = (psMetadata*)ctxt->sax->_private;
+    PS_PTR_CHECK_NULL_GENERAL(md, return);
+    input = (xmlParserInputPtr)ctxt->input;
+    PS_PTR_CHECK_NULL_GENERAL(input, return);
+    tables = psMetadataLookup(md, "htAtts");
+    PS_PTR_CHECK_NULL_GENERAL(tables, return);
+    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
+    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
+    htAtts = (psHash*)table->data.list;
+    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
+
+    // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems
+    psEndTagName = psStringCopy(tagName);
+
+    // Compare start and end tag names
+    psStartTagName = psHashLookup(htAtts, "tagName");
+    PS_PTR_CHECK_NULL_GENERAL(psStartTagName, return);
+    if(strcmp(psEndTagName, psStartTagName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH, psStartTagName, psEndTagName);
+    }
+
+    // Initialize psLib structs
+    if(!strcmp(psEndTagName, "psMetadataItem")) {
+        p_psInitMetadataItemXml(ctx, psEndTagName);
+    } else if(!strcmp(psEndTagName, "psVector")) {
+        p_psInitVectorXml(ctx, psEndTagName);
+    } else if(strcmp(psEndTagName, "psRoot")) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN, psEndTagName);
+    }
+
+    // Free temporary metadata item and its hash table
+    psListRemove(tables->data.list, PS_LIST_TAIL);
+
+    psFree(psEndTagName);
+
+    return;
+}
+
+psMetadata*  psMetadataParseConfigXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)
+{
+    xmlSAXHandler saxHandler;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(fileName, NULL);
+
+    // Allocate metadata if necessary
+    if (md == NULL) {
+        md = psMetadataAlloc();
+    }
+
+    // Sax handler initializations
+    saxHandler.internalSubset           = NULL;
+    saxHandler.isStandalone             = NULL;
+    saxHandler.hasInternalSubset        = NULL;
+    saxHandler.hasExternalSubset        = NULL;
+    saxHandler.resolveEntity            = NULL;
+    saxHandler.getEntity                = NULL;
+    saxHandler.entityDecl               = NULL;
+    saxHandler.notationDecl             = NULL;
+    saxHandler.attributeDecl            = NULL;
+    saxHandler.elementDecl              = NULL;
+    saxHandler.unparsedEntityDecl       = NULL;
+    saxHandler.setDocumentLocator       = NULL;
+    saxHandler.startDocument            = NULL;
+    saxHandler.endDocument              = NULL;
+    saxHandler.startElement             = p_saxStartElement;
+    saxHandler.endElement               = p_saxEndElement;
+    saxHandler.reference                = NULL;
+    saxHandler.characters               = NULL;
+    saxHandler.ignorableWhitespace      = NULL;
+    saxHandler.processingInstruction    = NULL;
+    saxHandler.comment                  = NULL;
+    saxHandler.warning                  = xmlParserError;
+    saxHandler.error                    = xmlParserError;
+    saxHandler.fatalError               = xmlParserError;
+    saxHandler.getParameterEntity       = NULL;
+    saxHandler.cdataBlock               = NULL;
+    saxHandler.externalSubset           = NULL;
+    saxHandler.initialized              = 1;
+    saxHandler._private                 = md;
+    saxHandler.startElementNs           = NULL;
+    saxHandler.endElementNs             = NULL;
+    saxHandler.serror                   = NULL;
+
+    // Parse XML file
+    if (xmlSAXUserParseFile(&saxHandler, NULL, fileName)) {
+        psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName);
+        return NULL;
+    }
+
+    // Parser and memory cleanups for libxml2
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return md;
+}
Index: /branches/rel4/psLib/src/xml/psXML.h
===================================================================
--- /branches/rel4/psLib/src/xml/psXML.h	(revision 3057)
+++ /branches/rel4/psLib/src/xml/psXML.h	(revision 3057)
@@ -0,0 +1,85 @@
+/** @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.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-06 20:00:03 $
+*
+*  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.
+ */
+bool psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* 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.
+    psS32 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 psMetadata* : Resulting metadata from read.
+ */
+psMetadata* psMetadataParseConfig(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/** Read XML metadata configuration file.
+ *
+ *  Loads pre-defined XML settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return psMetadata* : Resulting metadata from read.
+ */
+
+psMetadata*  psMetadataParseConfigXml(
+    psMetadata* md,                    ///< Resulting metadata from read.
+    psU32 *nFail,                      ///< Number of failed lines.
+    const char *fileName,              ///< Name of file to read.
+    psBool overwrite                   ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel4/psLib/tags
===================================================================
--- /branches/rel4/psLib/tags	(revision 3057)
+++ /branches/rel4/psLib/tags	(revision 3057)
@@ -0,0 +1,6084 @@
+!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME	Exuberant Ctags	//
+!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
+!_TAG_PROGRAM_VERSION	5.5.4	//
+A	test/dataManip/tst_psFunc07.c	/^#define A /;"	d	file:
+A	test/dataManip/tst_psMinimize04.c	/^#define A /;"	d	file:
+A	test/dataManip/tst_psMinimize04_F32.c	/^#define A /;"	d	file:
+A	test/dataManip/tst_psMinimize04b.c	/^#define A /;"	d	file:
+A	test/dataManip/tst_psMinimize04b_F32.c	/^#define A /;"	d	file:
+A	test/image/tst_psImageStats04.c	/^#define A /;"	d	file:
+AN	test/dataManip/tst_psFunc00.c	/^#define AN /;"	d	file:
+AND_OP	src/collections/psBitSet.c	/^    AND_OP,$/;"	e	file:
+ARCMIN_TO_RAD	test/astronomy/tst_psCoord.c	/^#define ARCMIN_TO_RAD /;"	d	file:
+ARCSEC_TO_RAD	test/astronomy/tst_psCoord.c	/^#define ARCSEC_TO_RAD /;"	d	file:
+AZ	test/astronomy/tst_psAstrometry01.c	/^#define AZ /;"	d	file:
+B	include/psMetadata.h	/^        psBool B;                      \/\/\/< boolean data$/;"	m	union:psMetadataItem::<anonymous>
+B	src/astronomy/psMetadata.h	/^        psBool B;                      \/\/\/< boolean data$/;"	m	union:psMetadataItem::<anonymous>
+B	test/dataManip/tst_psFunc07.c	/^#define B /;"	d	file:
+B	test/dataManip/tst_psMinimize04.c	/^#define B /;"	d	file:
+B	test/dataManip/tst_psMinimize04_F32.c	/^#define B /;"	d	file:
+B	test/dataManip/tst_psMinimize04b.c	/^#define B /;"	d	file:
+B	test/dataManip/tst_psMinimize04b_F32.c	/^#define B /;"	d	file:
+B	test/image/tst_psImageStats04.c	/^#define B /;"	d	file:
+BAD	test/dataManip/tst_psFunc00.c	/^#define BAD /;"	d	file:
+BINARY_OP	src/dataManip/psMatrixVectorArithmetic.c	/^#define BINARY_OP(/;"	d	file:
+BINARY_TYPE	src/dataManip/psMatrixVectorArithmetic.c	/^#define BINARY_TYPE(/;"	d	file:
+BN	test/dataManip/tst_psFunc00.c	/^#define BN /;"	d	file:
+C	test/dataManip/tst_psFunc07.c	/^#define C /;"	d	file:
+C	test/dataManip/tst_psMinimize04.c	/^#define C /;"	d	file:
+C	test/dataManip/tst_psMinimize04_F32.c	/^#define C /;"	d	file:
+C	test/dataManip/tst_psMinimize04b.c	/^#define C /;"	d	file:
+C	test/dataManip/tst_psMinimize04b_F32.c	/^#define C /;"	d	file:
+C	test/image/tst_psImageStats04.c	/^#define C /;"	d	file:
+C32	include/psImage.h	/^        psC32** C32;                   \/\/\/< Single-precision complex data.$/;"	m	union:psImage::<anonymous>
+C32	include/psScalar.h	/^        psC32 C32;              \/\/\/< Single-precision complex data.$/;"	m
+C32	include/psVector.h	/^        psC32* C32;             \/\/\/< Single-precision complex data.$/;"	m
+C32	src/collections/psScalar.h	/^        psC32 C32;              \/\/\/< Single-precision complex data.$/;"	m
+C32	src/collections/psVector.h	/^        psC32* C32;             \/\/\/< Single-precision complex data.$/;"	m
+C32	src/image/psImage.h	/^        psC32** C32;                   \/\/\/< Single-precision complex data.$/;"	m	union:psImage::<anonymous>
+C64	include/psImage.h	/^        psC64** C64;                   \/\/\/< Double-precision complex data.$/;"	m	union:psImage::<anonymous>
+C64	include/psScalar.h	/^        psC64 C64;              \/\/\/< Double-precision complex data.$/;"	m
+C64	include/psVector.h	/^        psC64* C64;             \/\/\/< Double-precision complex data.$/;"	m
+C64	src/collections/psScalar.h	/^        psC64 C64;              \/\/\/< Double-precision complex data.$/;"	m
+C64	src/collections/psVector.h	/^        psC64* C64;             \/\/\/< Double-precision complex data.$/;"	m
+C64	src/image/psImage.h	/^        psC64** C64;                   \/\/\/< Double-precision complex data.$/;"	m	union:psImage::<anonymous>
+CELL_GAP	test/astronomy/tst_psAstrometry01.c	/^#define CELL_GAP /;"	d	file:
+CELL_HEIGHT	test/astronomy/tst_psAstrometry01.c	/^#define CELL_HEIGHT /;"	d	file:
+CELL_MAX_X	test/astronomy/tst_psAstrometry01.c	/^#define CELL_MAX_X /;"	d	file:
+CELL_MAX_Y	test/astronomy/tst_psAstrometry01.c	/^#define CELL_MAX_Y /;"	d	file:
+CELL_MIN_X	test/astronomy/tst_psAstrometry01.c	/^#define CELL_MIN_X /;"	d	file:
+CELL_MIN_Y	test/astronomy/tst_psAstrometry01.c	/^#define CELL_MIN_Y /;"	d	file:
+CELL_WIDTH	test/astronomy/tst_psAstrometry01.c	/^#define CELL_WIDTH /;"	d	file:
+CHEBY_X_DIM	test/image/tst_psImageStats02.c	/^#define CHEBY_X_DIM /;"	d	file:
+CHEBY_Y_DIM	test/image/tst_psImageStats02.c	/^#define CHEBY_Y_DIM /;"	d	file:
+CHECK_INTERP_BY_TYPE	test/image/tst_psImageInterpolate.c	/^#define CHECK_INTERP_BY_TYPE(/;"	d	file:
+CHECK_INTERP_VALUE	test/image/tst_psImageInterpolate.c	/^#define CHECK_INTERP_VALUE(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix01.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix03.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix04.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix05.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix06.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrix07.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MATRIX	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^#define CHECK_MATRIX(/;"	d	file:
+CHECK_MEMORY	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define CHECK_MEMORY /;"	d	file:
+CHECK_MEMORY	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^#define CHECK_MEMORY /;"	d	file:
+CHECK_VALUE	test/dataManip/tst_psMatrix04.c	/^#define CHECK_VALUE(/;"	d	file:
+CHECK_VECTOR	test/dataManip/tst_psMatrix03.c	/^#define CHECK_VECTOR(/;"	d	file:
+CHECK_VECTOR	test/dataManip/tst_psMatrix07.c	/^#define CHECK_VECTOR(/;"	d	file:
+CHECK_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^#define CHECK_VECTOR(/;"	d	file:
+CHIP_GAP	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_GAP /;"	d	file:
+CHIP_HEIGHT	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_HEIGHT /;"	d	file:
+CHIP_MAX_X	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_MAX_X /;"	d	file:
+CHIP_MAX_Y	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_MAX_Y /;"	d	file:
+CHIP_MIN_X	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_MIN_X /;"	d	file:
+CHIP_MIN_Y	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_MIN_Y /;"	d	file:
+CHIP_WIDTH	test/astronomy/tst_psAstrometry01.c	/^#define CHIP_WIDTH /;"	d	file:
+CLEAR_TEMPS	src/astronomy/psMetadataIO.c	/^#define CLEAR_TEMPS(/;"	d	file:
+CN	test/dataManip/tst_psFunc00.c	/^#define CN /;"	d	file:
+COL0	test/astronomy/tst_psAstrometry01.c	/^#define COL0 /;"	d	file:
+COLOR	test/astronomy/tst_psCoord.c	/^#define COLOR /;"	d	file:
+COMPARE_NUMERIC	src/collections/psCompare.c	/^#define COMPARE_NUMERIC(/;"	d	file:
+COMPARE_NUMERIC_DESCENDING	src/collections/psCompare.c	/^#define COMPARE_NUMERIC_DESCENDING(/;"	d	file:
+COMPARE_NUMERIC_PTR	src/collections/psCompare.c	/^#define COMPARE_NUMERIC_PTR(/;"	d	file:
+COMPARE_NUMERIC_PTR_DESCENDING	src/collections/psCompare.c	/^#define COMPARE_NUMERIC_PTR_DESCENDING(/;"	d	file:
+CREATE_AND_SET_IMAGE	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define CREATE_AND_SET_IMAGE(/;"	d	file:
+CREATE_AND_SET_IMAGE	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^#define CREATE_AND_SET_IMAGE(/;"	d	file:
+CREATE_AND_SET_IMAGE	test/dataManip/tst_psMatrixVectorArithmetic03.c	/^#define CREATE_AND_SET_IMAGE(/;"	d	file:
+CREATE_AND_SET_IMAGE	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^#define CREATE_AND_SET_IMAGE(/;"	d	file:
+CREATE_AND_SET_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define CREATE_AND_SET_VECTOR(/;"	d	file:
+CREATE_AND_SET_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^#define CREATE_AND_SET_VECTOR(/;"	d	file:
+CREATE_AND_SET_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic03.c	/^#define CREATE_AND_SET_VECTOR(/;"	d	file:
+CREATE_AND_SET_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^#define CREATE_AND_SET_VECTOR(/;"	d	file:
+CUBIC	test/dataManip/tst_psFunc02.c	/^#define CUBIC /;"	d	file:
+CUBIC	test/dataManip/tst_psFunc03.c	/^#define CUBIC /;"	d	file:
+CalculateSecondDerivs	src/dataManip/psMinimize.c	/^psF32 *CalculateSecondDerivs(const psVector* restrict x,        \/\/\/< Ordinates (or NULL to just use the indices)$/;"	f
+Chi2PowellFunc	src/dataManip/psMinimize.c	/^static psMinimizeChi2PowellFunc Chi2PowellFunc = NULL;$/;"	v	file:
+D	include/psCoord.h	/^    double D;                   \/\/\/< Coordinates of projection center$/;"	m
+D	src/astronomy/psCoord.h	/^    double D;                   \/\/\/< Coordinates of projection center$/;"	m
+D	test/dataManip/tst_psFunc07.c	/^#define D /;"	d	file:
+D	test/dataManip/tst_psMinimize04b.c	/^#define D /;"	d	file:
+D	test/dataManip/tst_psMinimize04b_F32.c	/^#define D /;"	d	file:
+D	test/image/tst_psImageStats04.c	/^#define D /;"	d	file:
+D2R	src/dataManip/psMatrixVectorArithmetic.c	/^#define D2R /;"	d	file:
+DATA_WIDTH	test/dataManip/tst_psMinimize00.c	/^#define DATA_WIDTH /;"	d	file:
+DATA_WIDTH	test/dataManip/tst_psMinimize01.c	/^#define DATA_WIDTH /;"	d	file:
+DATA_WIDTH	test/dataManip/tst_psMinimize02.c	/^#define DATA_WIDTH /;"	d	file:
+DATA_WIDTH	test/dataManip/tst_psMinimize03.c	/^#define DATA_WIDTH /;"	d	file:
+DEC	test/astronomy/tst_psAstrometry01.c	/^#define DEC /;"	d	file:
+DEG_INC	test/astronomy/tst_psCoord.c	/^#define DEG_INC /;"	d	file:
+DEG_TO_RAD	src/astronomy/psCoord.c	/^#define DEG_TO_RAD(/;"	d	file:
+DEG_TO_RAD	test/astronomy/tst_psCoord.c	/^#define DEG_TO_RAD /;"	d	file:
+DN	test/dataManip/tst_psFunc00.c	/^#define DN /;"	d	file:
+E	test/dataManip/tst_psMinimize04b.c	/^#define E /;"	d	file:
+E	test/dataManip/tst_psMinimize04b_F32.c	/^#define E /;"	d	file:
+E	test/image/tst_psImageStats04.c	/^#define E /;"	d	file:
+ERROR_TOL	test/image/tst_psImageStats04.c	/^#define ERROR_TOL /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psFunc07.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psMinimize04.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psMinimize04_F32.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psMinimize04b.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psMinimize04b_F32.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psMinimize05.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psRandom.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERROR_TOLERANCE	test/dataManip/tst_psStats07.c	/^#define ERROR_TOLERANCE /;"	d	file:
+ERR_TOL	test/dataManip/tst_psMinimize06.c	/^#define ERR_TOL /;"	d	file:
+ERR_TOL	test/dataManip/tst_psMinimize07.c	/^#define ERR_TOL /;"	d	file:
+EXP_TIME	test/astronomy/tst_psAstrometry01.c	/^#define EXP_TIME /;"	d	file:
+F	test/image/tst_psImageStats04.c	/^#define F /;"	d	file:
+F32	include/psImage.h	/^        psF32** F32;                   \/\/\/< Single-precision float data.$/;"	m	union:psImage::<anonymous>
+F32	include/psMetadata.h	/^        psF32 F32;                     \/\/\/< Single-precision float data.$/;"	m	union:psMetadataItem::<anonymous>
+F32	include/psScalar.h	/^        psF32 F32;              \/\/\/< Single-precision float data.$/;"	m
+F32	include/psVector.h	/^        psF32* F32;             \/\/\/< Single-precision float data.$/;"	m
+F32	src/astronomy/psMetadata.h	/^        psF32 F32;                     \/\/\/< Single-precision float data.$/;"	m	union:psMetadataItem::<anonymous>
+F32	src/collections/psScalar.h	/^        psF32 F32;              \/\/\/< Single-precision float data.$/;"	m
+F32	src/collections/psVector.h	/^        psF32* F32;             \/\/\/< Single-precision float data.$/;"	m
+F32	src/image/psImage.h	/^        psF32** F32;                   \/\/\/< Single-precision float data.$/;"	m	union:psImage::<anonymous>
+F64	include/psImage.h	/^        psF64** F64;                   \/\/\/< Double-precision float data.$/;"	m	union:psImage::<anonymous>
+F64	include/psMetadata.h	/^        psF64 F64;                     \/\/\/< Double-precision float data.$/;"	m	union:psMetadataItem::<anonymous>
+F64	include/psScalar.h	/^        psF64 F64;              \/\/\/< Double-precision float data.$/;"	m
+F64	include/psVector.h	/^        psF64* F64;             \/\/\/< Double-precision float data.$/;"	m
+F64	src/astronomy/psMetadata.h	/^        psF64 F64;                     \/\/\/< Double-precision float data.$/;"	m	union:psMetadataItem::<anonymous>
+F64	src/collections/psScalar.h	/^        psF64 F64;              \/\/\/< Double-precision float data.$/;"	m
+F64	src/collections/psVector.h	/^        psF64* F64;             \/\/\/< Double-precision float data.$/;"	m
+F64	src/image/psImage.h	/^        psF64** F64;                   \/\/\/< Double-precision float data.$/;"	m	union:psImage::<anonymous>
+FITS_ERROR	src/astronomy/psMetadataIO.c	/^#define FITS_ERROR(/;"	d	file:
+FITS_LINE_SIZE	src/astronomy/psMetadataIO.c	/^#define FITS_LINE_SIZE /;"	d	file:
+FOURIER_PADDING	src/image/psImageConvolve.c	/^#define FOURIER_PADDING /;"	d	file:
+FPAFree	src/astronomy/psAstrometry.c	/^static void FPAFree(psFPA* fpa)$/;"	f	file:
+FPA_MAX_X	test/astronomy/tst_psAstrometry01.c	/^#define FPA_MAX_X /;"	d	file:
+FPA_MAX_Y	test/astronomy/tst_psAstrometry01.c	/^#define FPA_MAX_Y /;"	d	file:
+FPA_MIN_X	test/astronomy/tst_psAstrometry01.c	/^#define FPA_MIN_X /;"	d	file:
+FPA_MIN_Y	test/astronomy/tst_psAstrometry01.c	/^#define FPA_MIN_Y /;"	d	file:
+FUNC_MACRO_FULL_INTERPOLATE_1D	src/dataManip/psFunctions.c	/^#define FUNC_MACRO_FULL_INTERPOLATE_1D(/;"	d	file:
+FUNC_MACRO_VECTOR_BIN_DISECT	src/dataManip/psFunctions.c	/^#define FUNC_MACRO_VECTOR_BIN_DISECT(/;"	d	file:
+FUNC_MACRO_VECTOR_BIN_DISECT	src/dataManip/psFunctions.c	/^FUNC_MACRO_VECTOR_BIN_DISECT(S8)$/;"	f
+FitChebyF32	test/image/tst_psImageStats04.c	/^psS32 FitChebyF32(int numCols, int numRows)$/;"	f
+FitChebyF64	test/image/tst_psImageStats04.c	/^psS32 FitChebyF64(int numCols, int numRows)$/;"	f
+GAUSSIAN_MEAN	test/dataManip/tst_psRandom.c	/^#define GAUSSIAN_MEAN /;"	d	file:
+GAUSSIAN_STDEV	test/dataManip/tst_psRandom.c	/^#define GAUSSIAN_STDEV /;"	d	file:
+GENIMAGE	test/dataManip/tst_psVectorFFT.c	/^#define GENIMAGE(/;"	d	file:
+GENIMAGE	test/image/tst_psImageFFT.c	/^#define GENIMAGE(/;"	d	file:
+GENIMAGE	test/image/tst_psImageIO.c	/^#define GENIMAGE(/;"	d	file:
+GENIMAGE	test/image/tst_psImageInterpolate.c	/^#define GENIMAGE(/;"	d	file:
+HA	test/astronomy/tst_psAstrometry01.c	/^#define HA /;"	d	file:
+HEADER_BOTTOM	test/psTest.c	/^#define HEADER_BOTTOM /;"	d	file:
+HEADER_LINE_INT	test/psTest.c	/^#define HEADER_LINE_INT /;"	d	file:
+HEADER_LINE_STRING	test/psTest.c	/^#define HEADER_LINE_STRING /;"	d	file:
+HEADER_TOP	test/psTest.c	/^#define HEADER_TOP /;"	d	file:
+HEIGHT	test/astronomy/tst_psAstrometry01.c	/^#define HEIGHT /;"	d	file:
+HOST_NAME_MAX	src/sysUtils/psLogMsg.c	/^#define HOST_NAME_MAX /;"	d	file:
+HUMIDITY	test/astronomy/tst_psAstrometry01.c	/^#define HUMIDITY /;"	d	file:
+ID	include/psPhotometry.h	/^    const psS32 ID;               \/\/\/< ID number for this photometric system$/;"	m
+ID	src/astronomy/psPhotometry.h	/^    const psS32 ID;               \/\/\/< ID number for this photometric system$/;"	m
+ID	test/collections/tst_psHash01.c	/^ID;$/;"	t	file:
+ID	test/collections/tst_psHash02.c	/^ID;$/;"	t	file:
+ID	test/collections/tst_psHash03.c	/^ID;$/;"	t	file:
+ID	test/collections/tst_psHash04.c	/^ID;$/;"	t	file:
+IGNORE	test/dataManip/tst_psMinimize04b.c	/^#define IGNORE /;"	d	file:
+IGNORE	test/dataManip/tst_psMinimize04b_F32.c	/^#define IGNORE /;"	d	file:
+IMAGE	src/dataManip/psMatrixVectorArithmetic.c	/^#define IMAGE(/;"	d	file:
+IMAGE_IMAGE	src/dataManip/psMatrixVectorArithmetic.c	/^#define IMAGE_IMAGE(/;"	d	file:
+IMAGE_SCALAR	src/dataManip/psMatrixVectorArithmetic.c	/^#define IMAGE_SCALAR(/;"	d	file:
+IMAGE_SIZE	test/image/tst_psImageStats00.c	/^#define IMAGE_SIZE /;"	d	file:
+IMAGE_SIZE	test/image/tst_psImageStats02.c	/^#define IMAGE_SIZE /;"	d	file:
+IMAGE_SIZE	test/image/tst_psImageStats03.c	/^#define IMAGE_SIZE /;"	d	file:
+IMAGE_SIZE	test/image/tst_psImageStats04.c	/^#define IMAGE_SIZE /;"	d	file:
+IMAGE_VECTOR	src/dataManip/psMatrixVectorArithmetic.c	/^#define IMAGE_VECTOR(/;"	d	file:
+ITER_INIT_HEAD	src/collections/psList.c	/^#define ITER_INIT_HEAD /;"	d	file:
+ITER_INIT_TAIL	src/collections/psList.c	/^#define ITER_INIT_TAIL /;"	d	file:
+I_POLY	test/image/tst_psImageStats04.c	/^#define I_POLY(/;"	d	file:
+IdAlloc	test/collections/tst_psHash01.c	/^static ID *IdAlloc(const char *name)$/;"	f	file:
+IdAlloc	test/collections/tst_psHash02.c	/^static ID *IdAlloc(const char *name)$/;"	f	file:
+IdAlloc	test/collections/tst_psHash03.c	/^static ID *IdAlloc(const char *name)$/;"	f	file:
+IdAlloc	test/collections/tst_psHash04.c	/^static ID *IdAlloc(const char *name)$/;"	f	file:
+IdFree	test/collections/tst_psHash01.c	/^static void IdFree(ID *id)$/;"	f	file:
+IdFree	test/collections/tst_psHash01.c	/^static void IdFree(ID *id);$/;"	p	file:
+IdFree	test/collections/tst_psHash02.c	/^static void IdFree(ID *id)$/;"	f	file:
+IdFree	test/collections/tst_psHash02.c	/^static void IdFree(ID *id);$/;"	p	file:
+IdFree	test/collections/tst_psHash03.c	/^static void IdFree(ID *id)$/;"	f	file:
+IdFree	test/collections/tst_psHash03.c	/^static void IdFree(ID *id);$/;"	p	file:
+IdFree	test/collections/tst_psHash04.c	/^static void IdFree(ID *id)$/;"	f	file:
+IdFree	test/collections/tst_psHash04.c	/^static void IdFree(ID *id);$/;"	p	file:
+KERNEL_GENERATE_CASE	src/image/psImageConvolve.c	/^    #define KERNEL_GENERATE_CASE(/;"	d	file:
+LAPSERATE	test/astronomy/tst_psAstrometry01.c	/^#define LAPSERATE /;"	d	file:
+LATITUDE	test/astronomy/tst_psAstrometry01.c	/^#define LATITUDE /;"	d	file:
+LINEAR	test/dataManip/tst_psFunc02.c	/^#define LINEAR /;"	d	file:
+LINEAR	test/dataManip/tst_psFunc03.c	/^#define LINEAR /;"	d	file:
+LINEAR_CUT_CASE	src/image/psImageExtraction.c	/^    #define LINEAR_CUT_CASE(/;"	d	file:
+LONGITUDE	test/astronomy/tst_psAstrometry01.c	/^#define LONGITUDE /;"	d	file:
+LOWER	test/dataManip/tst_psHist00.c	/^#define LOWER /;"	d	file:
+LOWER	test/dataManip/tst_psHist01.c	/^#define LOWER /;"	d	file:
+LOWER	test/dataManip/tst_psHist02.c	/^#define LOWER /;"	d	file:
+LOWER	test/dataManip/tst_psHist03.c	/^#define LOWER /;"	d	file:
+M	test/image/tst_psImageStats00.c	/^#define M /;"	d	file:
+M	test/image/tst_psImageStats01.c	/^#define M /;"	d	file:
+MAGNITUDE	test/astronomy/tst_psCoord.c	/^#define MAGNITUDE /;"	d	file:
+MAX	test/dataManip/tst_psFunc07.c	/^#define MAX /;"	d	file:
+MAX_ERROR_STACK_SIZE	src/sysUtils/psError.c	/^#define MAX_ERROR_STACK_SIZE /;"	d	file:
+MAX_LOG_LEVEL	src/sysUtils/psLogMsg.c	/^#define MAX_LOG_LEVEL /;"	d	file:
+MAX_LOG_LINE_LENGTH	src/sysUtils/psLogMsg.c	/^#define MAX_LOG_LINE_LENGTH /;"	d	file:
+MAX_STRING_LENGTH	src/astronomy/psMetadata.c	/^#define MAX_STRING_LENGTH /;"	d	file:
+MAX_STRING_LENGTH	src/astronomy/psMetadataIO.c	/^#define MAX_STRING_LENGTH /;"	d	file:
+MAX_STRING_LENGTH	src/astronomy/psTime.c	/^#define MAX_STRING_LENGTH /;"	d	file:
+MAX_STRING_LENGTH	src/fileUtils/psFits.c	/^#define MAX_STRING_LENGTH /;"	d	file:
+MAX_STRING_LENGTH	src/fileUtils/psLookupTable.c	/^#define MAX_STRING_LENGTH /;"	d	file:
+MAX_TIME_STRING_LENGTH	src/astronomy/psTime.c	/^                #define MAX_TIME_STRING_LENGTH /;"	d	file:
+MEAN	test/dataManip/tst_psMinimize07.c	/^#define MEAN /;"	d	file:
+MEAN	test/dataManip/tst_psStats07.c	/^#define MEAN /;"	d	file:
+MIN	test/dataManip/tst_psFunc07.c	/^#define MIN /;"	d	file:
+MIN_LOG_LEVEL	src/sysUtils/psLogMsg.c	/^#define MIN_LOG_LEVEL /;"	d	file:
+MIN_TO_RAD	src/astronomy/psCoord.c	/^#define MIN_TO_RAD(/;"	d	file:
+MIN_VALUE	test/dataManip/tst_psMinimize05.c	/^#define MIN_VALUE /;"	d	file:
+MIN_VALUE	test/dataManip/tst_psMinimize06.c	/^#define MIN_VALUE /;"	d	file:
+MISC_FLOAT_NUMBER	test/dataManip/tst_psFunc00.c	/^#define MISC_FLOAT_NUMBER /;"	d	file:
+MISC_FLOAT_NUMBER	test/dataManip/tst_psHist02.c	/^#define MISC_FLOAT_NUMBER /;"	d	file:
+MISC_FLOAT_NUMBER	test/dataManip/tst_psStats05.c	/^#define MISC_FLOAT_NUMBER /;"	d	file:
+MISC_INT_NUMBER	test/dataManip/tst_psFunc00.c	/^#define MISC_INT_NUMBER /;"	d	file:
+MISC_INT_NUMBER	test/dataManip/tst_psHist02.c	/^#define MISC_INT_NUMBER /;"	d	file:
+MISC_X_CHEB_VALUE	test/dataManip/tst_psFunc00.c	/^#define MISC_X_CHEB_VALUE /;"	d	file:
+MISC_X_VALUE	test/dataManip/tst_psFunc00.c	/^#define MISC_X_VALUE /;"	d	file:
+MY_MEAN	test/dataManip/tst_psFunc01.c	/^#define MY_MEAN /;"	d	file:
+MY_MEAN	test/dataManip/tst_psStats09.c	/^#define MY_MEAN /;"	d	file:
+MY_RANGE	test/dataManip/tst_psStats09.c	/^#define MY_RANGE /;"	d	file:
+MY_STDEV	test/dataManip/tst_psFunc01.c	/^#define MY_STDEV /;"	d	file:
+MY_TINY	test/astronomy/tst_psCoord.c	/^#define MY_TINY /;"	d	file:
+N	test/astronomy/tst_psCoord.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psFunc01.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psFunc02.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psFunc03.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psFunc04.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psFunc05.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psMinimize05.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psMinimize06.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psMinimize07.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats00.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats01.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats02.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats03.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats04.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats06.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats07.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats08.c	/^#define N /;"	d	file:
+N	test/dataManip/tst_psStats09.c	/^#define N /;"	d	file:
+N	test/image/tst_psImageStats00.c	/^#define N /;"	d	file:
+N	test/image/tst_psImageStats01.c	/^#define N /;"	d	file:
+N1	test/dataManip/tst_psStats03.c	/^#define N1 /;"	d	file:
+N1	test/dataManip/tst_psStats04.c	/^#define N1 /;"	d	file:
+N1	test/dataManip/tst_psStats08.c	/^#define N1 /;"	d	file:
+NAME	test/astronomy/tst_psAstrometry01.c	/^#define NAME /;"	d	file:
+NOT_OP	src/collections/psBitSet.c	/^    NOT_OP$/;"	e	file:
+NPLAT	test/astronomy/tst_psCoord.c	/^#define NPLAT /;"	d	file:
+NUM_BINS	test/image/tst_psImageStats00.c	/^#define NUM_BINS /;"	d	file:
+NUM_BINS	test/image/tst_psImageStats01.c	/^#define NUM_BINS /;"	d	file:
+NUM_CELLS	test/astronomy/tst_psAstrometry01.c	/^#define NUM_CELLS /;"	d	file:
+NUM_CHIPS	test/astronomy/tst_psAstrometry01.c	/^#define NUM_CHIPS /;"	d	file:
+NUM_COLS	test/image/tst_psImageStats04.c	/^#define NUM_COLS /;"	d	file:
+NUM_DATA	test/dataManip/tst_psHist02.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psHist03.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize00.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize01.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize04.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize04_F32.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize04b.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psMinimize04b_F32.c	/^#define NUM_DATA /;"	d	file:
+NUM_DATA	test/dataManip/tst_psRandom.c	/^#define NUM_DATA /;"	d	file:
+NUM_HASH_TABLE_BUCKETS	test/collections/tst_psHash00.c	/^#define NUM_HASH_TABLE_BUCKETS /;"	d	file:
+NUM_HASH_TABLE_BUCKETS	test/collections/tst_psHash01.c	/^#define NUM_HASH_TABLE_BUCKETS /;"	d	file:
+NUM_HASH_TABLE_BUCKETS	test/collections/tst_psHash02.c	/^#define NUM_HASH_TABLE_BUCKETS /;"	d	file:
+NUM_HASH_TABLE_BUCKETS	test/collections/tst_psHash03.c	/^#define NUM_HASH_TABLE_BUCKETS /;"	d	file:
+NUM_HASH_TABLE_BUCKETS	test/collections/tst_psHash04.c	/^#define NUM_HASH_TABLE_BUCKETS /;"	d	file:
+NUM_ITERATIONS	test/dataManip/tst_psMinimize06.c	/^#define NUM_ITERATIONS /;"	d	file:
+NUM_ITERATIONS	test/dataManip/tst_psMinimize07.c	/^#define NUM_ITERATIONS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize00.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize01.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize02.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize03.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize05.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize06.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_PARAMS	test/dataManip/tst_psMinimize07.c	/^#define NUM_PARAMS /;"	d	file:
+NUM_READOUTS	test/astronomy/tst_psAstrometry01.c	/^#define NUM_READOUTS /;"	d	file:
+NUM_ROWS	test/image/tst_psImageStats04.c	/^#define NUM_ROWS /;"	d	file:
+NUM_SPLINES	test/dataManip/tst_psFunc07.c	/^#define NUM_SPLINES /;"	d	file:
+NW_TERMS	test/astronomy/tst_psCoord.c	/^#define NW_TERMS /;"	d	file:
+NX_TERMS	test/astronomy/tst_psCoord.c	/^#define NX_TERMS /;"	d	file:
+NY_TERMS	test/astronomy/tst_psCoord.c	/^#define NY_TERMS /;"	d	file:
+NZ_TERMS	test/astronomy/tst_psCoord.c	/^#define NZ_TERMS /;"	d	file:
+OFFSET	test/dataManip/tst_psFunc07.c	/^#define OFFSET /;"	d	file:
+ORDER	test/dataManip/tst_psFunc00.c	/^#define ORDER /;"	d	file:
+OR_OP	src/collections/psBitSet.c	/^    OR_OP,$/;"	e	file:
+POISSON_MEAN	test/dataManip/tst_psRandom.c	/^#define POISSON_MEAN /;"	d	file:
+POISSON_STDEV	test/dataManip/tst_psRandom.c	/^#define POISSON_STDEV /;"	d	file:
+POLY_ORDER	test/dataManip/tst_psMinimize04.c	/^#define POLY_ORDER /;"	d	file:
+POLY_ORDER	test/dataManip/tst_psMinimize04_F32.c	/^#define POLY_ORDER /;"	d	file:
+POLY_ORDER	test/dataManip/tst_psMinimize04b.c	/^#define POLY_ORDER /;"	d	file:
+POLY_ORDER	test/dataManip/tst_psMinimize04b_F32.c	/^#define POLY_ORDER /;"	d	file:
+PRESSURE	test/astronomy/tst_psAstrometry01.c	/^#define PRESSURE /;"	d	file:
+PRINT_MATRIX	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define PRINT_MATRIX(/;"	d	file:
+PRINT_MATRIX	test/dataManip/tst_psMatrixVectorArithmetic03.c	/^#define PRINT_MATRIX(/;"	d	file:
+PRINT_SCALAR	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define PRINT_SCALAR(/;"	d	file:
+PRINT_TIME	test/astronomy/tst_psTime_03.c	/^#define PRINT_TIME(/;"	d	file:
+PRINT_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^#define PRINT_VECTOR(/;"	d	file:
+PRINT_VECTOR	test/dataManip/tst_psMatrixVectorArithmetic03.c	/^#define PRINT_VECTOR(/;"	d	file:
+PSBITSET_H	include/psBitSet.h	/^#define PSBITSET_H$/;"	d
+PSBITSET_H	src/collections/psBitSet.h	/^#define PSBITSET_H$/;"	d
+PSELEMTYPE_SIZEOF	include/psType.h	/^#define PSELEMTYPE_SIZEOF(/;"	d
+PSELEMTYPE_SIZEOF	src/sysUtils/psType.h	/^#define PSELEMTYPE_SIZEOF(/;"	d
+PSIMAGEEXTRACTION_H	include/psImageExtraction.h	/^#define PSIMAGEEXTRACTION_H$/;"	d
+PSIMAGEEXTRACTION_H	src/image/psImageExtraction.h	/^#define PSIMAGEEXTRACTION_H$/;"	d
+PSIMAGESLICE_TEST	test/image/tst_psImageExtraction.c	/^    #define PSIMAGESLICE_TEST(/;"	d	file:
+PSIMAGESLICE_TEST1	test/image/tst_psImageExtraction.c	/^    #define PSIMAGESLICE_TEST1(/;"	d	file:
+PSIMAGE_COPY_CASE	src/image/psImage.c	/^    #define PSIMAGE_COPY_CASE(/;"	d	file:
+PSIMAGE_CUT_VERTICAL	src/image/psImageExtraction.c	/^        #define PSIMAGE_CUT_VERTICAL(/;"	d	file:
+PSIMAGE_ELEMENT_COPY	src/image/psImage.c	/^    #define PSIMAGE_ELEMENT_COPY(/;"	d	file:
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR	src/image/psImage.c	/^#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(/;"	d	file:
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX	src/image/psImage.c	/^#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(/;"	d	file:
+PSIMAGE_PIXEL_INTERPOLATE_CASE	src/image/psImage.c	/^    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(/;"	d	file:
+PSIMAGE_PIXEL_INTERPOLATE_FLAT	src/image/psImage.c	/^#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(/;"	d	file:
+PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX	src/image/psImage.c	/^#define PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(/;"	d	file:
+PSIMAGE_RESAMPLE_CASE	src/image/psImageManip.c	/^    #define PSIMAGE_RESAMPLE_CASE(/;"	d	file:
+PSIMAGE_ROTATE_180_CASE	src/image/psImageManip.c	/^        #define PSIMAGE_ROTATE_180_CASE(/;"	d	file:
+PSIMAGE_ROTATE_ARBITRARY_CASE	src/image/psImageManip.c	/^        #define PSIMAGE_ROTATE_ARBITRARY_CASE(/;"	d	file:
+PSIMAGE_ROTATE_ARBITRARY_LOOP	src/image/psImageManip.c	/^        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(/;"	d	file:
+PSIMAGE_ROTATE_LEFT_90	src/image/psImageManip.c	/^        #define PSIMAGE_ROTATE_LEFT_90(/;"	d	file:
+PSIMAGE_ROTATE_RIGHT_90	src/image/psImageManip.c	/^        #define PSIMAGE_ROTATE_RIGHT_90(/;"	d	file:
+PSIMAGE_SHIFT_ARBITRARY_CASE	src/image/psImageManip.c	/^    #define PSIMAGE_SHIFT_ARBITRARY_CASE(/;"	d	file:
+PSIMAGE_SHIFT_CASE	src/image/psImageManip.c	/^    #define PSIMAGE_SHIFT_CASE(/;"	d	file:
+PSMATRIX_H	include/psMatrix.h	/^#define PSMATRIX_H$/;"	d
+PSMATRIX_H	src/dataManip/psMatrix.h	/^#define PSMATRIX_H$/;"	d
+PSMATRIX_VECTOR_ARITHMETIC_H	include/psMatrixVectorArithmetic.h	/^#define PSMATRIX_VECTOR_ARITHMETIC_H$/;"	d
+PSMATRIX_VECTOR_ARITHMETIC_H	src/dataManip/psMatrixVectorArithmetic.h	/^#define PSMATRIX_VECTOR_ARITHMETIC_H$/;"	d
+PSTEST_H	include/psTest.h	/^#define PSTEST_H$/;"	d
+PSTEST_H	test/psTest.h	/^#define PSTEST_H$/;"	d
+PSTIME_H	include/psTime.h	/^#define PSTIME_H$/;"	d
+PSTIME_H	src/astronomy/psTime.h	/^#define PSTIME_H$/;"	d
+PSVECTOR_COPY	src/collections/psVector.c	/^    #define PSVECTOR_COPY(/;"	d	file:
+PSVECTOR_COPY_CASE	src/collections/psVector.c	/^    #define PSVECTOR_COPY_CASE(/;"	d	file:
+PS_ABORT_H	include/psAbort.h	/^#define PS_ABORT_H$/;"	d
+PS_ABORT_H	src/sysUtils/psAbort.h	/^#define PS_ABORT_H$/;"	d
+PS_ALLOW_MALLOC	src/sysUtils/psMemory.c	/^#define PS_ALLOW_MALLOC /;"	d	file:
+PS_ALLOW_MALLOC	test/sysUtils/tst_psMemory.c	/^#define PS_ALLOW_MALLOC /;"	d	file:
+PS_ARCMIN	include/psCoord.h	/^    PS_ARCMIN,                  \/\/\/< Arcminutes$/;"	e
+PS_ARCMIN	src/astronomy/psCoord.h	/^    PS_ARCMIN,                  \/\/\/< Arcminutes$/;"	e
+PS_ARCSEC	include/psCoord.h	/^    PS_ARCSEC,                  \/\/\/< Arcseconds$/;"	e
+PS_ARCSEC	src/astronomy/psCoord.h	/^    PS_ARCSEC,                  \/\/\/< Arcseconds$/;"	e
+PS_ARRAY_H	include/psArray.h	/^#define PS_ARRAY_H$/;"	d
+PS_ARRAY_H	src/collections/psArray.h	/^#define PS_ARRAY_H$/;"	d
+PS_ASTROMETRY_H	include/psAstrometry.h	/^#define PS_ASTROMETRY_H$/;"	d
+PS_ASTROMETRY_H	src/astronomy/psAstrometry.h	/^#define PS_ASTROMETRY_H$/;"	d
+PS_ASTRONOMY_ERRORS_H	src/astronomy/psAstronomyErrors.h	/^#define PS_ASTRONOMY_ERRORS_H$/;"	d
+PS_BADPIXEL_BITMASK	include/psType.h	/^#define PS_BADPIXEL_BITMASK /;"	d
+PS_BADPIXEL_BITMASK	src/sysUtils/psType.h	/^#define PS_BADPIXEL_BITMASK /;"	d
+PS_BIN_MIDPOINT	src/dataManip/psStats.c	/^#define PS_BIN_MIDPOINT(/;"	d	file:
+PS_CHECK_DIMEN_AND_TYPE	src/dataManip/psMatrix.c	/^#define PS_CHECK_DIMEN_AND_TYPE(/;"	d	file:
+PS_CHECK_POINTERS	src/dataManip/psMatrix.c	/^#define PS_CHECK_POINTERS(/;"	d	file:
+PS_CHECK_SQUARE	src/dataManip/psMatrix.c	/^#define PS_CHECK_SQUARE(/;"	d	file:
+PS_CLIPPED_NUM_ITER_LB	src/dataManip/psStats.c	/^#define PS_CLIPPED_NUM_ITER_LB /;"	d	file:
+PS_CLIPPED_NUM_ITER_UB	src/dataManip/psStats.c	/^#define PS_CLIPPED_NUM_ITER_UB /;"	d	file:
+PS_CLIPPED_SIGMA_LB	src/dataManip/psStats.c	/^#define PS_CLIPPED_SIGMA_LB /;"	d	file:
+PS_CLIPPED_SIGMA_UB	src/dataManip/psStats.c	/^#define PS_CLIPPED_SIGMA_UB /;"	d	file:
+PS_COLLECTIONS_ERRORS_H	src/collections/psCollectionsErrors.h	/^#define PS_COLLECTIONS_ERRORS_H$/;"	d
+PS_COMPARE_EPSILON_THEN_PRINT_ERROR	test/astronomy/tst_psCoord.c	/^#define PS_COMPARE_EPSILON_THEN_PRINT_ERROR(/;"	d	file:
+PS_COMPARE_H	include/psCompare.h	/^#define PS_COMPARE_H$/;"	d
+PS_COMPARE_H	src/collections/psCompare.h	/^#define PS_COMPARE_H$/;"	d
+PS_COMPARE_TINY_THEN_PRINT_ERROR	test/astronomy/tst_psCoord.c	/^#define PS_COMPARE_TINY_THEN_PRINT_ERROR(/;"	d	file:
+PS_CONFIGURE_H	include/psConfigure.h	/^#define PS_CONFIGURE_H$/;"	d
+PS_CONFIGURE_H	src/sysUtils/psConfigure.h	/^#define PS_CONFIGURE_H$/;"	d
+PS_COORD_H	include/psCoord.h	/^#define PS_COORD_H$/;"	d
+PS_COORD_H	src/astronomy/psCoord.h	/^#define PS_COORD_H$/;"	d
+PS_COT	src/astronomy/psCoord.c	/^#define PS_COT(/;"	d	file:
+PS_COT	test/astronomy/tst_psCoord.c	/^#define PS_COT(/;"	d	file:
+PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM	test/astronomy/tst_psAstrometry01.c	/^#define PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(/;"	d	file:
+PS_CREATE_4D_IDENTITY_PLANE_DISTORT	test/astronomy/tst_psAstrometry01.c	/^#define PS_CREATE_4D_IDENTITY_PLANE_DISTORT(/;"	d	file:
+PS_CUT_X_NEG	include/psImageExtraction.h	/^    PS_CUT_X_NEG,                      \/\/\/< Cut in the x dimension from rigth to left$/;"	e
+PS_CUT_X_NEG	src/image/psImageExtraction.h	/^    PS_CUT_X_NEG,                      \/\/\/< Cut in the x dimension from rigth to left$/;"	e
+PS_CUT_X_POS	include/psImageExtraction.h	/^    PS_CUT_X_POS,                      \/\/\/< Cut in the x dimension from left to right$/;"	e
+PS_CUT_X_POS	src/image/psImageExtraction.h	/^    PS_CUT_X_POS,                      \/\/\/< Cut in the x dimension from left to right$/;"	e
+PS_CUT_Y_NEG	include/psImageExtraction.h	/^    PS_CUT_Y_NEG,                      \/\/\/< Cut in the y dimension from top down.$/;"	e
+PS_CUT_Y_NEG	src/image/psImageExtraction.h	/^    PS_CUT_Y_NEG,                      \/\/\/< Cut in the y dimension from top down.$/;"	e
+PS_CUT_Y_POS	include/psImageExtraction.h	/^    PS_CUT_Y_POS,                      \/\/\/< Cut in the y dimension from bottom up$/;"	e
+PS_CUT_Y_POS	src/image/psImageExtraction.h	/^    PS_CUT_Y_POS,                      \/\/\/< Cut in the y dimension from bottom up$/;"	e
+PS_DATAMANIP_ERRORS_H	src/dataManip/psDataManipErrors.h	/^#define PS_DATAMANIP_ERRORS_H$/;"	d
+PS_DEFAULT_TRACE_LEVEL	include/psTrace.h	/^#define PS_DEFAULT_TRACE_LEVEL /;"	d
+PS_DEFAULT_TRACE_LEVEL	src/sysUtils/psTrace.h	/^#define PS_DEFAULT_TRACE_LEVEL /;"	d
+PS_DEGREE	include/psCoord.h	/^    PS_DEGREE,                  \/\/\/< Degrees$/;"	e
+PS_DEGREE	src/astronomy/psCoord.h	/^    PS_DEGREE,                  \/\/\/< Degrees$/;"	e
+PS_DETERMINE_BRACKET_MAX_ITERATIONS	src/dataManip/psMinimize.c	/^#define PS_DETERMINE_BRACKET_MAX_ITERATIONS /;"	d	file:
+PS_DETERMINE_BRACKET_STEP_SIZE	include/psConstants.h	/^#define PS_DETERMINE_BRACKET_STEP_SIZE /;"	d
+PS_DETERMINE_BRACKET_STEP_SIZE	src/dataManip/psConstants.h	/^#define PS_DETERMINE_BRACKET_STEP_SIZE /;"	d
+PS_DIMEN_IMAGE	include/psType.h	/^    PS_DIMEN_IMAGE,             \/\/\/< Image.$/;"	e
+PS_DIMEN_IMAGE	src/sysUtils/psType.h	/^    PS_DIMEN_IMAGE,             \/\/\/< Image.$/;"	e
+PS_DIMEN_OTHER	include/psType.h	/^    PS_DIMEN_OTHER              \/\/\/< Something else that's not supported for arithmetic.$/;"	e
+PS_DIMEN_OTHER	src/sysUtils/psType.h	/^    PS_DIMEN_OTHER              \/\/\/< Something else that's not supported for arithmetic.$/;"	e
+PS_DIMEN_SCALAR	include/psType.h	/^    PS_DIMEN_SCALAR,            \/\/\/< Scalar.$/;"	e
+PS_DIMEN_SCALAR	src/sysUtils/psType.h	/^    PS_DIMEN_SCALAR,            \/\/\/< Scalar.$/;"	e
+PS_DIMEN_TRANSV	include/psType.h	/^    PS_DIMEN_TRANSV,            \/\/\/< Transposed vector.$/;"	e
+PS_DIMEN_TRANSV	src/sysUtils/psType.h	/^    PS_DIMEN_TRANSV,            \/\/\/< Transposed vector.$/;"	e
+PS_DIMEN_VECTOR	include/psType.h	/^    PS_DIMEN_VECTOR,            \/\/\/< Vector.$/;"	e
+PS_DIMEN_VECTOR	src/sysUtils/psType.h	/^    PS_DIMEN_VECTOR,            \/\/\/< Vector.$/;"	e
+PS_ERRORNAME_DOMAIN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORNAME_DOMAIN	src/collections/psCollectionsErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORNAME_DOMAIN	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORNAME_DOMAIN	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORNAME_DOMAIN	src/image/psImageErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORNAME_DOMAIN	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORNAME_DOMAIN /;"	d
+PS_ERRORTEXT_psArray_REALLOC_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psArray_REALLOC_NULL /;"	d
+PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM /;"	d
+PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE /;"	d
+PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE /;"	d
+PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL /;"	d
+PS_ERRORTEXT_psBitSet_NOT_OP_FAILED	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_NOT_OP_FAILED /;"	d
+PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER /;"	d
+PS_ERRORTEXT_psBitSet_OPERAND_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_OPERAND_NULL /;"	d
+PS_ERRORTEXT_psBitSet_OPERATOR_INVALID	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_OPERATOR_INVALID /;"	d
+PS_ERRORTEXT_psBitSet_OPERATOR_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_OPERATOR_NULL /;"	d
+PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL /;"	d
+PS_ERRORTEXT_psBitSet_SET_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psBitSet_SET_NULL /;"	d
+PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED /;"	d
+PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED /;"	d
+PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN /;"	d
+PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED /;"	d
+PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN /;"	d
+PS_ERRORTEXT_psCoord_UNITS_UNKNOWN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psCoord_UNITS_UNKNOWN /;"	d
+PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED /;"	d
+PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION /;"	d
+PS_ERRORTEXT_psFits_CFITSIO_ERROR	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_CFITSIO_ERROR /;"	d
+PS_ERRORTEXT_psFits_CREATE_HDU_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_CREATE_HDU_FAILED /;"	d
+PS_ERRORTEXT_psFits_EXTNAME_INVALID	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_EXTNAME_INVALID /;"	d
+PS_ERRORTEXT_psFits_EXTNUM_INVALID	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_EXTNUM_INVALID /;"	d
+PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_FILENAME_CREATE_FAILED /;"	d
+PS_ERRORTEXT_psFits_FILENAME_INVALID	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_FILENAME_INVALID /;"	d
+PS_ERRORTEXT_psFits_FILENAME_NULL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_FILENAME_NULL /;"	d
+PS_ERRORTEXT_psFits_FIND_COLUMN	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_FIND_COLUMN /;"	d
+PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GETHDUTYPE_FAILED /;"	d
+PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GETNUMHDUS_FAILED /;"	d
+PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GETNUMKEYS_FAILED /;"	d
+PS_ERRORTEXT_psFits_GET_COLTYPE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GET_COLTYPE /;"	d
+PS_ERRORTEXT_psFits_GET_EXTNUM_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GET_EXTNUM_FAILED /;"	d
+PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED /;"	d
+PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GET_TABLE_ELEMENT /;"	d
+PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_GET_TABLE_SIZE_FAILED /;"	d
+PS_ERRORTEXT_psFits_IMAGE_NULL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_IMAGE_NULL /;"	d
+PS_ERRORTEXT_psFits_METADATA_ADD_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_METADATA_ADD_FAILED /;"	d
+PS_ERRORTEXT_psFits_METADATA_NULL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_METADATA_NULL /;"	d
+PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_METADATA_PTYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psFits_METATYPE_INVALID	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_METATYPE_INVALID /;"	d
+PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE /;"	d
+PS_ERRORTEXT_psFits_NOT_TABLE_TYPE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE /;"	d
+PS_ERRORTEXT_psFits_NULL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_NULL /;"	d
+PS_ERRORTEXT_psFits_ROW_INVALID	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_ROW_INVALID /;"	d
+PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL /;"	d
+PS_ERRORTEXT_psFits_TABLE_READ_COL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_TABLE_READ_COL /;"	d
+PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psFits_WRITE_FAILED	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psFits_WRITE_FAILED /;"	d
+PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE /;"	d
+PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS /;"	d
+PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED /;"	d
+PS_ERRORTEXT_psHash_DATA_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psHash_DATA_NULL /;"	d
+PS_ERRORTEXT_psHash_KEY_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psHash_KEY_NULL /;"	d
+PS_ERRORTEXT_psHash_TABLE_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psHash_TABLE_NULL /;"	d
+PS_ERRORTEXT_psImageConvolve_FFT_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_FFT_FAILED /;"	d
+PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED /;"	d
+PS_ERRORTEXT_psImageConvolve_KERNEL_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_KERNEL_NULL /;"	d
+PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE /;"	d
+PS_ERRORTEXT_psImageConvolve_SHIFT_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_SHIFT_NULL /;"	d
+PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL /;"	d
+PS_ERRORTEXT_psImageFFT_FORWARD_NOT_REAL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_FORWARD_NOT_REAL /;"	d
+PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE /;"	d
+PS_ERRORTEXT_psImageFFT_IMAGE_TYPE_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_IMAGE_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION /;"	d
+PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH /;"	d
+PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psImageFFT_REVERSE_NOT_COMPLEX	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageFFT_REVERSE_NOT_COMPLEX /;"	d
+PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED /;"	d
+PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED /;"	d
+PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN /;"	d
+PS_ERRORTEXT_psImageIO_EXTNAME_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_EXTNAME_INVALID /;"	d
+PS_ERRORTEXT_psImageIO_EXTNUM_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_EXTNUM_INVALID /;"	d
+PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED /;"	d
+PS_ERRORTEXT_psImageIO_FILENAME_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_FILENAME_INVALID /;"	d
+PS_ERRORTEXT_psImageIO_FILENAME_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_FILENAME_NULL /;"	d
+PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN /;"	d
+PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN /;"	d
+PS_ERRORTEXT_psImageIO_READ_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_READ_FAILED /;"	d
+PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID /;"	d
+PS_ERRORTEXT_psImageIO_WRITE_FAILED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageIO_WRITE_FAILED /;"	d
+PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID /;"	d
+PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImageManip_MAXMIN	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_MAXMIN /;"	d
+PS_ERRORTEXT_psImageManip_MAXMIN_IMAG	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_MAXMIN_IMAG /;"	d
+PS_ERRORTEXT_psImageManip_MAXMIN_REAL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_MAXMIN_REAL /;"	d
+PS_ERRORTEXT_psImageManip_OPERATION_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_OPERATION_NULL /;"	d
+PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID /;"	d
+PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE /;"	d
+PS_ERRORTEXT_psImage_AREA_NEGATIVE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_AREA_NEGATIVE /;"	d
+PS_ERRORTEXT_psImage_BAD_STAT	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_BAD_STAT /;"	d
+PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE /;"	d
+PS_ERRORTEXT_psImage_COEFF_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_COEFF_NULL /;"	d
+PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE /;"	d
+PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE /;"	d
+PS_ERRORTEXT_psImage_IMAGE_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_IMAGE_NULL /;"	d
+PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID /;"	d
+PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE /;"	d
+PS_ERRORTEXT_psImage_NOT_AN_IMAGE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_NOT_AN_IMAGE /;"	d
+PS_ERRORTEXT_psImage_NOT_PARENT	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_NOT_PARENT /;"	d
+PS_ERRORTEXT_psImage_NO_STAT_OPTIONS	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_NO_STAT_OPTIONS /;"	d
+PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE /;"	d
+PS_ERRORTEXT_psImage_RADII_VECTOR_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_RADII_VECTOR_NULL /;"	d
+PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL /;"	d
+PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID /;"	d
+PS_ERRORTEXT_psImage_STAT_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_STAT_NULL /;"	d
+PS_ERRORTEXT_psImage_SUBSECTION_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SUBSECTION_INVALID /;"	d
+PS_ERRORTEXT_psImage_SUBSECTION_NULL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SUBSECTION_NULL /;"	d
+PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID /;"	d
+PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED /;"	d
+PS_ERRORTEXT_psImage_SUBSET_ZERO_SIZE	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_SUBSET_ZERO_SIZE /;"	d
+PS_ERRORTEXT_psImage_nSamples_TOOSMALL	src/image/psImageErrors.h	/^#define PS_ERRORTEXT_psImage_nSamples_TOOSMALL /;"	d
+PS_ERRORTEXT_psList_DATA_NOT_FOUND	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_DATA_NOT_FOUND /;"	d
+PS_ERRORTEXT_psList_DATA_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_DATA_NULL /;"	d
+PS_ERRORTEXT_psList_ITERATOR_INVALID	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_ITERATOR_INVALID /;"	d
+PS_ERRORTEXT_psList_ITERATOR_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_ITERATOR_NULL /;"	d
+PS_ERRORTEXT_psList_LIST_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_LIST_NULL /;"	d
+PS_ERRORTEXT_psList_LOCATION_INVALID	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psList_LOCATION_INVALID /;"	d
+PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED /;"	d
+PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID /;"	d
+PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED /;"	d
+PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY /;"	d
+PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL /;"	d
+PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_DIVIDE_BY_ZERO /;"	d
+PS_ERRORTEXT_psLookupTable_FILE_NOT_FOUND	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_FILE_NOT_FOUND /;"	d
+PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_HIGH /;"	d
+PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_INTERPOLATE_LOW /;"	d
+PS_ERRORTEXT_psLookupTable_INVALID_TYPE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_INVALID_TYPE /;"	d
+PS_ERRORTEXT_psLookupTable_PARSE_GENERAL	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_PARSE_GENERAL /;"	d
+PS_ERRORTEXT_psLookupTable_PARSE_TYPE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_PARSE_TYPE /;"	d
+PS_ERRORTEXT_psLookupTable_PARSE_VALUE	src/fileUtils/psFileUtilsErrors.h	/^#define PS_ERRORTEXT_psLookupTable_PARSE_VALUE /;"	d
+PS_ERRORTEXT_psMatrix_COUNT_DIFFERS	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_COUNT_DIFFERS /;"	d
+PS_ERRORTEXT_psMatrix_DIMEN_INVALID	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_DIMEN_INVALID /;"	d
+PS_ERRORTEXT_psMatrix_DIMEN_OTHER_FOUND	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_DIMEN_OTHER_FOUND /;"	d
+PS_ERRORTEXT_psMatrix_IMAGE_EMPTY	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_IMAGE_EMPTY /;"	d
+PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS /;"	d
+PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT /;"	d
+PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT /;"	d
+PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED /;"	d
+PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED /;"	d
+PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH /;"	d
+PS_ERRORTEXT_psMatrix_TYPE_MISMATCH	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psMatrix_VECTOR_EMPTY	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psMatrix_VECTOR_EMPTY /;"	d
+PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE /;"	d
+PS_ERRORTEXT_psMemory_MULTIPLE_FREE	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psMemory_MULTIPLE_FREE /;"	d
+PS_ERRORTEXT_psMemory_NULL_BLOCK	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psMemory_NULL_BLOCK /;"	d
+PS_ERRORTEXT_psMemory_OVERFLOW	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psMemory_OVERFLOW /;"	d
+PS_ERRORTEXT_psMemory_UNDERFLOW	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psMemory_UNDERFLOW /;"	d
+PS_ERRORTEXT_psMetadataIO_ADD_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_ADD_FAILED /;"	d
+PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE /;"	d
+PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL /;"	d
+PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR /;"	d
+PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED /;"	d
+PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID /;"	d
+PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID /;"	d
+PS_ERRORTEXT_psMetadataIO_NO_NAME	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_NO_NAME /;"	d
+PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM /;"	d
+PS_ERRORTEXT_psMetadataIO_PARSE_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_PARSE_FAILED /;"	d
+PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH /;"	d
+PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN /;"	d
+PS_ERRORTEXT_psMetadataIO_TYPE_INVALID	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID /;"	d
+PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE /;"	d
+PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_ADD_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_ADD_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_FIND_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_FIND_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_METATYPE_INVALID	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_METATYPE_INVALID /;"	d
+PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED /;"	d
+PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED /;"	d
+PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE /;"	d
+PS_ERRORTEXT_psScalar_COPY_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psScalar_COPY_NULL /;"	d
+PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE /;"	d
+PS_ERRORTEXT_psStats_NOT_F32_F64	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_NOT_F32_F64 /;"	d
+PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED /;"	d
+PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS /;"	d
+PS_ERRORTEXT_psStats_STATS_FAILED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_FAILED /;"	d
+PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT /;"	d
+PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN /;"	d
+PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE /;"	d
+PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM /;"	d
+PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM /;"	d
+PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE /;"	d
+PS_ERRORTEXT_psString_NCHAR_NEGATIVE	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psString_NCHAR_NEGATIVE /;"	d
+PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED /;"	d
+PS_ERRORTEXT_psTime_BAD_TABLE_COUNT	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_BAD_TABLE_COUNT /;"	d
+PS_ERRORTEXT_psTime_BAD_VECTOR	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_BAD_VECTOR /;"	d
+PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED /;"	d
+PS_ERRORTEXT_psTime_FILE_NOT_FOUND	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_FILE_NOT_FOUND /;"	d
+PS_ERRORTEXT_psTime_FILE_TOO_MANY_ROWS	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_FILE_TOO_MANY_ROWS /;"	d
+PS_ERRORTEXT_psTime_GET_TOD_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_GET_TOD_FAILED /;"	d
+PS_ERRORTEXT_psTime_INTERPOLATION_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED /;"	d
+PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME /;"	d
+PS_ERRORTEXT_psTime_ISOTIME_MALFORMED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_ISOTIME_MALFORMED /;"	d
+PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED /;"	d
+PS_ERRORTEXT_psTime_TABLE_DUPLICATE_ROWS	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TABLE_DUPLICATE_ROWS /;"	d
+PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLE	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLE /;"	d
+PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES /;"	d
+PS_ERRORTEXT_psTime_TIME_PREDATES_TABLE	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLE /;"	d
+PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES /;"	d
+PS_ERRORTEXT_psTime_TYPE_INCORRECT	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TYPE_INCORRECT /;"	d
+PS_ERRORTEXT_psTime_TYPE_MISMATCH	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psTime_TYPE_UNKNOWN	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_TYPE_UNKNOWN /;"	d
+PS_ERRORTEXT_psTime_USEC_INVALID	src/astronomy/psAstronomyErrors.h	/^#define PS_ERRORTEXT_psTime_USEC_INVALID /;"	d
+PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT /;"	d
+PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT /;"	d
+PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME /;"	d
+PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT /;"	d
+PS_ERRORTEXT_psTrace_NULL_TRACETREE	src/sysUtils/psSysUtilsErrors.h	/^#define PS_ERRORTEXT_psTrace_NULL_TRACETREE /;"	d
+PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET /;"	d
+PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL /;"	d
+PS_ERRORTEXT_psVectorFFT_FORWARD_NOT_REAL	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_FORWARD_NOT_REAL /;"	d
+PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED /;"	d
+PS_ERRORTEXT_psVectorFFT_REAL_IMAG_SIZE_MISMATCH	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_SIZE_MISMATCH /;"	d
+PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH /;"	d
+PS_ERRORTEXT_psVectorFFT_REVERSE_NOT_COMPLEX	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_REVERSE_NOT_COMPLEX /;"	d
+PS_ERRORTEXT_psVectorFFT_TYPE_NOT_F32_C32	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_TYPE_NOT_F32_C32 /;"	d
+PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED	src/dataManip/psDataManipErrors.h	/^#define PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED /;"	d
+PS_ERRORTEXT_psVector_NOT_A_VECTOR	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psVector_NOT_A_VECTOR /;"	d
+PS_ERRORTEXT_psVector_REALLOC_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psVector_REALLOC_NULL /;"	d
+PS_ERRORTEXT_psVector_SORT_NULL	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psVector_SORT_NULL /;"	d
+PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE	src/collections/psCollectionsErrors.h	/^#define PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE /;"	d
+PS_ERROR_CODES_H	include/psErrorCodes.h	/^#define PS_ERROR_CODES_H$/;"	d
+PS_ERROR_CODES_H	src/sysUtils/psErrorCodes.h	/^#define PS_ERROR_CODES_H$/;"	d
+PS_ERROR_H	include/psError.h	/^#define PS_ERROR_H$/;"	d
+PS_ERROR_H	src/sysUtils/psError.h	/^#define PS_ERROR_H$/;"	d
+PS_ERR_BAD_PARAMETER_NULL	include/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_NULL,   \/\/\/< parameter is null$/;"	e
+PS_ERR_BAD_PARAMETER_NULL	src/sysUtils/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_NULL,   \/\/\/< parameter is null$/;"	e
+PS_ERR_BAD_PARAMETER_SIZE	include/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_SIZE,   \/\/\/< size of parameter's data is outside of acceptable range.$/;"	e
+PS_ERR_BAD_PARAMETER_SIZE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_SIZE,   \/\/\/< size of parameter's data is outside of acceptable range.$/;"	e
+PS_ERR_BAD_PARAMETER_TYPE	include/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_TYPE,   \/\/\/< parameter is of unsupported type$/;"	e
+PS_ERR_BAD_PARAMETER_TYPE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_TYPE,   \/\/\/< parameter is of unsupported type$/;"	e
+PS_ERR_BAD_PARAMETER_VALUE	include/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_VALUE,   \/\/\/< parameter is out-of-range$/;"	e
+PS_ERR_BAD_PARAMETER_VALUE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_BAD_PARAMETER_VALUE,   \/\/\/< parameter is out-of-range$/;"	e
+PS_ERR_BASE	include/psErrorCodes.h	/^    PS_ERR_BASE = 256,$/;"	e
+PS_ERR_BASE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_BASE = 256,$/;"	e
+PS_ERR_IO	include/psErrorCodes.h	/^    PS_ERR_IO,   \/\/\/< I\/O error$/;"	e
+PS_ERR_IO	src/sysUtils/psErrorCodes.h	/^    PS_ERR_IO,   \/\/\/< I\/O error$/;"	e
+PS_ERR_LOCATION_INVALID	include/psErrorCodes.h	/^    PS_ERR_LOCATION_INVALID,   \/\/\/< specified location is unknown$/;"	e
+PS_ERR_LOCATION_INVALID	src/sysUtils/psErrorCodes.h	/^    PS_ERR_LOCATION_INVALID,   \/\/\/< specified location is unknown$/;"	e
+PS_ERR_MEMORY_CORRUPTION	include/psErrorCodes.h	/^    PS_ERR_MEMORY_CORRUPTION,   \/\/\/< memory corruption detected$/;"	e
+PS_ERR_MEMORY_CORRUPTION	src/sysUtils/psErrorCodes.h	/^    PS_ERR_MEMORY_CORRUPTION,   \/\/\/< memory corruption detected$/;"	e
+PS_ERR_MEMORY_DEREF_USAGE	include/psErrorCodes.h	/^    PS_ERR_MEMORY_DEREF_USAGE,   \/\/\/< dereferenced memory still used$/;"	e
+PS_ERR_MEMORY_DEREF_USAGE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_MEMORY_DEREF_USAGE,   \/\/\/< dereferenced memory still used$/;"	e
+PS_ERR_NONE	include/psErrorCodes.h	/^    PS_ERR_NONE = 0,                   \/\/\/< not an error$/;"	e
+PS_ERR_NONE	src/sysUtils/psErrorCodes.h	/^    PS_ERR_NONE = 0,                   \/\/\/< not an error$/;"	e
+PS_ERR_N_ERR_CLASSES	include/psErrorCodes.h	/^    PS_ERR_N_ERR_CLASSES               \/\/\/< end marker - should not be used as a true error$/;"	e
+PS_ERR_N_ERR_CLASSES	src/sysUtils/psErrorCodes.h	/^    PS_ERR_N_ERR_CLASSES               \/\/\/< end marker - should not be used as a true error$/;"	e
+PS_ERR_OS_CALL_FAILED	include/psErrorCodes.h	/^    PS_ERR_OS_CALL_FAILED,   \/\/\/< unexpected result from an OS standard library call$/;"	e
+PS_ERR_OS_CALL_FAILED	src/sysUtils/psErrorCodes.h	/^    PS_ERR_OS_CALL_FAILED,   \/\/\/< unexpected result from an OS standard library call$/;"	e
+PS_ERR_UNEXPECTED_NULL	include/psErrorCodes.h	/^    PS_ERR_UNEXPECTED_NULL,   \/\/\/< unexpected NULL found$/;"	e
+PS_ERR_UNEXPECTED_NULL	src/sysUtils/psErrorCodes.h	/^    PS_ERR_UNEXPECTED_NULL,   \/\/\/< unexpected NULL found$/;"	e
+PS_ERR_UNKNOWN	include/psErrorCodes.h	/^    PS_ERR_UNKNOWN,   \/\/\/< unknown error$/;"	e
+PS_ERR_UNKNOWN	src/sysUtils/psErrorCodes.h	/^    PS_ERR_UNKNOWN,   \/\/\/< unknown error$/;"	e
+PS_FFTW_PLAN_RIGOR	src/image/psImageFFT.c	/^#define PS_FFTW_PLAN_RIGOR /;"	d	file:
+PS_FFT_FORWARD	include/psVectorFFT.h	/^    PS_FFT_FORWARD = 1,$/;"	e
+PS_FFT_FORWARD	src/dataManip/psVectorFFT.h	/^    PS_FFT_FORWARD = 1,$/;"	e
+PS_FFT_REAL_RESULT	include/psVectorFFT.h	/^    PS_FFT_REAL_RESULT = 4$/;"	e
+PS_FFT_REAL_RESULT	src/dataManip/psVectorFFT.h	/^    PS_FFT_REAL_RESULT = 4$/;"	e
+PS_FFT_REVERSE	include/psVectorFFT.h	/^    PS_FFT_REVERSE = 2,$/;"	e
+PS_FFT_REVERSE	src/dataManip/psVectorFFT.h	/^    PS_FFT_REVERSE = 2,$/;"	e
+PS_FILE	src/dataManip/psMinimize.c	/^#define PS_FILE /;"	d	file:
+PS_FILEUTIL_ERRORS_H	src/fileUtils/psFileUtilsErrors.h	/^#define PS_FILEUTIL_ERRORS_H$/;"	d
+PS_FITS_H	src/fileUtils/psFits.h	/^#define PS_FITS_H$/;"	d
+PS_FITS_TYPE_ANY	src/fileUtils/psFits.h	/^    PS_FITS_TYPE_ANY = ANY_HDU$/;"	e
+PS_FITS_TYPE_ASCII_TABLE	src/fileUtils/psFits.h	/^    PS_FITS_TYPE_ASCII_TABLE = ASCII_TBL,$/;"	e
+PS_FITS_TYPE_BINARY_TABLE	src/fileUtils/psFits.h	/^    PS_FITS_TYPE_BINARY_TABLE = BINARY_TBL,$/;"	e
+PS_FITS_TYPE_IMAGE	src/fileUtils/psFits.h	/^    PS_FITS_TYPE_IMAGE = IMAGE_HDU,$/;"	e
+PS_FITS_TYPE_NONE	src/fileUtils/psFits.h	/^    PS_FITS_TYPE_NONE = -1,$/;"	e
+PS_FLOAT_CHECK_NON_EQUAL	include/psConstants.h	/^#define PS_FLOAT_CHECK_NON_EQUAL(/;"	d
+PS_FLOAT_CHECK_NON_EQUAL	src/dataManip/psConstants.h	/^#define PS_FLOAT_CHECK_NON_EQUAL(/;"	d
+PS_FLOAT_CHECK_RANGE	include/psConstants.h	/^#define PS_FLOAT_CHECK_RANGE(/;"	d
+PS_FLOAT_CHECK_RANGE	src/dataManip/psConstants.h	/^#define PS_FLOAT_CHECK_RANGE(/;"	d
+PS_FLOAT_COMPARE	include/psConstants.h	/^#define PS_FLOAT_COMPARE(/;"	d
+PS_FLOAT_COMPARE	src/dataManip/psConstants.h	/^#define PS_FLOAT_COMPARE(/;"	d
+PS_FUNCTIONS_H	include/psFunctions.h	/^#define PS_FUNCTIONS_H$/;"	d
+PS_FUNCTIONS_H	src/dataManip/psFunctions.h	/^#define PS_FUNCTIONS_H$/;"	d
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE	src/dataManip/psStats.c	/^#define PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(/;"	d	file:
+PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE	src/dataManip/psStats.c	/^PS_FUNC_MACRO_NORMALIZE_VECTOR_RANGE(U8)$/;"	f
+PS_GAUSS_WIDTH	src/dataManip/psStats.c	/^#define PS_GAUSS_WIDTH /;"	d	file:
+PS_GET_BADPIXEL	include/psType.h	/^#define PS_GET_BADPIXEL(/;"	d
+PS_GET_BADPIXEL	src/sysUtils/psType.h	/^#define PS_GET_BADPIXEL(/;"	d
+PS_GSL_MATRIX_INITIALIZE	src/dataManip/psMatrix.c	/^#define PS_GSL_MATRIX_INITIALIZE(/;"	d	file:
+PS_HASH_H	include/psHash.h	/^#define PS_HASH_H$/;"	d
+PS_HASH_H	src/collections/psHash.h	/^#define PS_HASH_H$/;"	d
+PS_IMAGEIO_H	include/psImageIO.h	/^#define PS_IMAGEIO_H$/;"	d
+PS_IMAGEIO_H	src/image/psImageIO.h	/^#define PS_IMAGEIO_H$/;"	d
+PS_IMAGE_CHECK_EMPTY	include/psConstants.h	/^#define PS_IMAGE_CHECK_EMPTY(/;"	d
+PS_IMAGE_CHECK_EMPTY	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_EMPTY(/;"	d
+PS_IMAGE_CHECK_EMPTY_GENERAL	include/psConstants.h	/^#define PS_IMAGE_CHECK_EMPTY_GENERAL(/;"	d
+PS_IMAGE_CHECK_EMPTY_GENERAL	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_EMPTY_GENERAL(/;"	d
+PS_IMAGE_CHECK_NULL	include/psConstants.h	/^#define PS_IMAGE_CHECK_NULL(/;"	d
+PS_IMAGE_CHECK_NULL	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_NULL(/;"	d
+PS_IMAGE_CHECK_NULL_GENERAL	include/psConstants.h	/^#define PS_IMAGE_CHECK_NULL_GENERAL(/;"	d
+PS_IMAGE_CHECK_NULL_GENERAL	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_NULL_GENERAL(/;"	d
+PS_IMAGE_CHECK_SIZE	include/psConstants.h	/^#define PS_IMAGE_CHECK_SIZE(/;"	d
+PS_IMAGE_CHECK_SIZE	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_SIZE(/;"	d
+PS_IMAGE_CHECK_SIZE_EQUAL	include/psConstants.h	/^#define PS_IMAGE_CHECK_SIZE_EQUAL(/;"	d
+PS_IMAGE_CHECK_SIZE_EQUAL	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_SIZE_EQUAL(/;"	d
+PS_IMAGE_CHECK_TYPE	include/psConstants.h	/^#define PS_IMAGE_CHECK_TYPE(/;"	d
+PS_IMAGE_CHECK_TYPE	src/dataManip/psConstants.h	/^#define PS_IMAGE_CHECK_TYPE(/;"	d
+PS_IMAGE_CONVOLVE_H	include/psImageConvolve.h	/^#define PS_IMAGE_CONVOLVE_H$/;"	d
+PS_IMAGE_CONVOLVE_H	src/image/psImageConvolve.h	/^#define PS_IMAGE_CONVOLVE_H$/;"	d
+PS_IMAGE_ERRORS_H	src/image/psImageErrors.h	/^#define PS_IMAGE_ERRORS_H$/;"	d
+PS_IMAGE_FFT_H	include/psImageFFT.h	/^#define PS_IMAGE_FFT_H$/;"	d
+PS_IMAGE_FFT_H	src/image/psImageFFT.h	/^#define PS_IMAGE_FFT_H$/;"	d
+PS_IMAGE_H	include/psImage.h	/^#define PS_IMAGE_H$/;"	d
+PS_IMAGE_H	src/image/psImage.h	/^#define PS_IMAGE_H$/;"	d
+PS_IMAGE_MANIP_H	include/psImageManip.h	/^#define PS_IMAGE_MANIP_H$/;"	d
+PS_IMAGE_MANIP_H	src/image/psImageManip.h	/^#define PS_IMAGE_MANIP_H$/;"	d
+PS_IMAGE_PRINT_F32	include/psConstants.h	/^#define PS_IMAGE_PRINT_F32(/;"	d
+PS_IMAGE_PRINT_F32	src/dataManip/psConstants.h	/^#define PS_IMAGE_PRINT_F32(/;"	d
+PS_IMAGE_REBIN_CASE	src/image/psImageManip.c	/^    #define PS_IMAGE_REBIN_CASE(/;"	d	file:
+PS_IMAGE_SET_F32	include/psConstants.h	/^#define PS_IMAGE_SET_F32(/;"	d
+PS_IMAGE_SET_F32	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_F32(/;"	d
+PS_IMAGE_SET_F64	include/psConstants.h	/^#define PS_IMAGE_SET_F64(/;"	d
+PS_IMAGE_SET_F64	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_F64(/;"	d
+PS_IMAGE_SET_S16	include/psConstants.h	/^#define PS_IMAGE_SET_S16(/;"	d
+PS_IMAGE_SET_S16	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_S16(/;"	d
+PS_IMAGE_SET_S32	include/psConstants.h	/^#define PS_IMAGE_SET_S32(/;"	d
+PS_IMAGE_SET_S32	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_S32(/;"	d
+PS_IMAGE_SET_S64	include/psConstants.h	/^#define PS_IMAGE_SET_S64(/;"	d
+PS_IMAGE_SET_S64	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_S64(/;"	d
+PS_IMAGE_SET_S8	include/psConstants.h	/^#define PS_IMAGE_SET_S8(/;"	d
+PS_IMAGE_SET_S8	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_S8(/;"	d
+PS_IMAGE_SET_U16	include/psConstants.h	/^#define PS_IMAGE_SET_U16(/;"	d
+PS_IMAGE_SET_U16	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_U16(/;"	d
+PS_IMAGE_SET_U32	include/psConstants.h	/^#define PS_IMAGE_SET_U32(/;"	d
+PS_IMAGE_SET_U32	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_U32(/;"	d
+PS_IMAGE_SET_U64	include/psConstants.h	/^#define PS_IMAGE_SET_U64(/;"	d
+PS_IMAGE_SET_U64	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_U64(/;"	d
+PS_IMAGE_SET_U8	include/psConstants.h	/^#define PS_IMAGE_SET_U8(/;"	d
+PS_IMAGE_SET_U8	src/dataManip/psConstants.h	/^#define PS_IMAGE_SET_U8(/;"	d
+PS_IMAGE_STATS_H	include/psImageStats.h	/^#define PS_IMAGE_STATS_H$/;"	d
+PS_IMAGE_STATS_H	src/image/psImageStats.h	/^#define PS_IMAGE_STATS_H$/;"	d
+PS_INTERPOLATE_BICUBIC	include/psImage.h	/^    PS_INTERPOLATE_BICUBIC,            \/\/\/< bi-cubic interpolation$/;"	e
+PS_INTERPOLATE_BICUBIC	src/image/psImage.h	/^    PS_INTERPOLATE_BICUBIC,            \/\/\/< bi-cubic interpolation$/;"	e
+PS_INTERPOLATE_BILINEAR	include/psImage.h	/^    PS_INTERPOLATE_BILINEAR,           \/\/\/< bi-linear interpolation$/;"	e
+PS_INTERPOLATE_BILINEAR	src/image/psImage.h	/^    PS_INTERPOLATE_BILINEAR,           \/\/\/< bi-linear interpolation$/;"	e
+PS_INTERPOLATE_FLAT	include/psImage.h	/^    PS_INTERPOLATE_FLAT = 1,           \/\/\/< 'flat' interpolation (nearest pixel)$/;"	e
+PS_INTERPOLATE_FLAT	src/image/psImage.h	/^    PS_INTERPOLATE_FLAT = 1,           \/\/\/< 'flat' interpolation (nearest pixel)$/;"	e
+PS_INTERPOLATE_NUM_MODES	include/psImage.h	/^    PS_INTERPOLATE_NUM_MODES           \/\/\/< end-marker of list of modes; not a valid interpolation mode$/;"	e
+PS_INTERPOLATE_NUM_MODES	src/image/psImage.h	/^    PS_INTERPOLATE_NUM_MODES           \/\/\/< end-marker of list of modes; not a valid interpolation mode$/;"	e
+PS_INTERPOLATE_SINC	include/psImage.h	/^    PS_INTERPOLATE_SINC,               \/\/\/< sinc interpolation$/;"	e
+PS_INTERPOLATE_SINC	src/image/psImage.h	/^    PS_INTERPOLATE_SINC,               \/\/\/< sinc interpolation$/;"	e
+PS_INT_CHECK_EQUALS	include/psConstants.h	/^#define PS_INT_CHECK_EQUALS(/;"	d
+PS_INT_CHECK_EQUALS	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_EQUALS(/;"	d
+PS_INT_CHECK_NON_EQUALS	include/psConstants.h	/^#define PS_INT_CHECK_NON_EQUALS(/;"	d
+PS_INT_CHECK_NON_EQUALS	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_NON_EQUALS(/;"	d
+PS_INT_CHECK_NON_NEGATIVE	include/psConstants.h	/^#define PS_INT_CHECK_NON_NEGATIVE(/;"	d
+PS_INT_CHECK_NON_NEGATIVE	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_NON_NEGATIVE(/;"	d
+PS_INT_CHECK_POSITIVE	include/psConstants.h	/^#define PS_INT_CHECK_POSITIVE(/;"	d
+PS_INT_CHECK_POSITIVE	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_POSITIVE(/;"	d
+PS_INT_CHECK_RANGE	include/psConstants.h	/^#define PS_INT_CHECK_RANGE(/;"	d
+PS_INT_CHECK_RANGE	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_RANGE(/;"	d
+PS_INT_CHECK_ZERO	include/psConstants.h	/^#define PS_INT_CHECK_ZERO(/;"	d
+PS_INT_CHECK_ZERO	src/dataManip/psConstants.h	/^#define PS_INT_CHECK_ZERO(/;"	d
+PS_INT_COMPARE	include/psConstants.h	/^#define PS_INT_COMPARE(/;"	d
+PS_INT_COMPARE	src/dataManip/psConstants.h	/^#define PS_INT_COMPARE(/;"	d
+PS_IS_BADPIXEL	include/psType.h	/^#define PS_IS_BADPIXEL(/;"	d
+PS_IS_BADPIXEL	src/sysUtils/psType.h	/^#define PS_IS_BADPIXEL(/;"	d
+PS_IS_PSELEMTYPE_BOOL	include/psType.h	/^#define PS_IS_PSELEMTYPE_BOOL(/;"	d
+PS_IS_PSELEMTYPE_BOOL	src/sysUtils/psType.h	/^#define PS_IS_PSELEMTYPE_BOOL(/;"	d
+PS_IS_PSELEMTYPE_COMPLEX	include/psType.h	/^#define PS_IS_PSELEMTYPE_COMPLEX(/;"	d
+PS_IS_PSELEMTYPE_COMPLEX	src/sysUtils/psType.h	/^#define PS_IS_PSELEMTYPE_COMPLEX(/;"	d
+PS_IS_PSELEMTYPE_INT	include/psType.h	/^#define PS_IS_PSELEMTYPE_INT(/;"	d
+PS_IS_PSELEMTYPE_INT	src/sysUtils/psType.h	/^#define PS_IS_PSELEMTYPE_INT(/;"	d
+PS_IS_PSELEMTYPE_REAL	include/psType.h	/^#define PS_IS_PSELEMTYPE_REAL(/;"	d
+PS_IS_PSELEMTYPE_REAL	src/sysUtils/psType.h	/^#define PS_IS_PSELEMTYPE_REAL(/;"	d
+PS_IS_PSELEMTYPE_UNSIGNED	include/psType.h	/^#define PS_IS_PSELEMTYPE_UNSIGNED(/;"	d
+PS_IS_PSELEMTYPE_UNSIGNED	src/sysUtils/psType.h	/^#define PS_IS_PSELEMTYPE_UNSIGNED(/;"	d
+PS_LEFT_SPLINE_DERIV	include/psConstants.h	/^#define PS_LEFT_SPLINE_DERIV /;"	d
+PS_LEFT_SPLINE_DERIV	src/dataManip/psConstants.h	/^#define PS_LEFT_SPLINE_DERIV /;"	d
+PS_LIB_H	include/pslib.h	/^#define PS_LIB_H$/;"	d
+PS_LIB_H	src/pslib.h	/^#define PS_LIB_H$/;"	d
+PS_LINEAR	include/psCoord.h	/^    PS_LINEAR                   \/\/\/< offset corresponds to a linear offset$/;"	e
+PS_LINEAR	src/astronomy/psCoord.h	/^    PS_LINEAR                   \/\/\/< offset corresponds to a linear offset$/;"	e
+PS_LINEMIN_MAX_ITERATIONS	src/dataManip/psMinimize.c	/^#define PS_LINEMIN_MAX_ITERATIONS /;"	d	file:
+PS_LIST_H	include/psList.h	/^#define PS_LIST_H$/;"	d
+PS_LIST_H	src/collections/psList.h	/^#define PS_LIST_H$/;"	d
+PS_LIST_HEAD	include/psList.h	/^    PS_LIST_HEAD = 0,                  \/\/\/< at head$/;"	e
+PS_LIST_HEAD	src/collections/psList.h	/^    PS_LIST_HEAD = 0,                  \/\/\/< at head$/;"	e
+PS_LIST_TAIL	include/psList.h	/^    PS_LIST_TAIL = -1,                 \/\/\/< at tail$/;"	e
+PS_LIST_TAIL	src/collections/psList.h	/^    PS_LIST_TAIL = -1,                 \/\/\/< at tail$/;"	e
+PS_LOG_ABORT	include/psLogMsg.h	/^    PS_LOG_ABORT = 0,                  \/\/\/< log message is a critical error, perform an abort after printing$/;"	e
+PS_LOG_ABORT	src/sysUtils/psLogMsg.h	/^    PS_LOG_ABORT = 0,                  \/\/\/< log message is a critical error, perform an abort after printing$/;"	e
+PS_LOG_ERROR	include/psLogMsg.h	/^    PS_LOG_ERROR,                      \/\/\/< log message is an error, but don't abort$/;"	e
+PS_LOG_ERROR	src/sysUtils/psLogMsg.h	/^    PS_LOG_ERROR,                      \/\/\/< log message is an error, but don't abort$/;"	e
+PS_LOG_INFO	include/psLogMsg.h	/^    PS_LOG_INFO                        \/\/\/< log message is informational only$/;"	e
+PS_LOG_INFO	src/sysUtils/psLogMsg.h	/^    PS_LOG_INFO                        \/\/\/< log message is informational only$/;"	e
+PS_LOG_MSG_H	include/psLogMsg.h	/^#define PS_LOG_MSG_H$/;"	d
+PS_LOG_MSG_H	src/sysUtils/psLogMsg.h	/^#define PS_LOG_MSG_H$/;"	d
+PS_LOG_NONE	include/psLogMsg.h	/^    PS_LOG_NONE,                       \/\/\/< turn off logging$/;"	e
+PS_LOG_NONE	src/sysUtils/psLogMsg.h	/^    PS_LOG_NONE,                       \/\/\/< turn off logging$/;"	e
+PS_LOG_TO_STDERR	include/psLogMsg.h	/^    PS_LOG_TO_STDERR,                  \/\/\/< log to system's stderr$/;"	e
+PS_LOG_TO_STDERR	src/sysUtils/psLogMsg.h	/^    PS_LOG_TO_STDERR,                  \/\/\/< log to system's stderr$/;"	e
+PS_LOG_TO_STDOUT	include/psLogMsg.h	/^    PS_LOG_TO_STDOUT                   \/\/\/< log to system's stdout$/;"	e
+PS_LOG_TO_STDOUT	src/sysUtils/psLogMsg.h	/^    PS_LOG_TO_STDOUT                   \/\/\/< log to system's stdout$/;"	e
+PS_LOG_WARN	include/psLogMsg.h	/^    PS_LOG_WARN,                       \/\/\/< log message is a warning$/;"	e
+PS_LOG_WARN	src/sysUtils/psLogMsg.h	/^    PS_LOG_WARN,                       \/\/\/< log message is a warning$/;"	e
+PS_LOOKUPTABLE_H	include/psLookupTable.h	/^#define PS_LOOKUPTABLE_H$/;"	d
+PS_LOOKUPTABLE_H	src/fileUtils/psLookupTable.h	/^#define PS_LOOKUPTABLE_H$/;"	d
+PS_LOOKUP_ERROR	include/psLookupTable.h	/^    PS_LOOKUP_ERROR               = 0x0104         \/\/\/< Any other type of lookup error$/;"	e
+PS_LOOKUP_ERROR	src/fileUtils/psLookupTable.h	/^    PS_LOOKUP_ERROR               = 0x0104         \/\/\/< Any other type of lookup error$/;"	e
+PS_LOOKUP_PAST_BOTTOM	include/psLookupTable.h	/^    PS_LOOKUP_PAST_BOTTOM         = 0x0102,        \/\/\/< Lookup off bottom of table$/;"	e
+PS_LOOKUP_PAST_BOTTOM	src/fileUtils/psLookupTable.h	/^    PS_LOOKUP_PAST_BOTTOM         = 0x0102,        \/\/\/< Lookup off bottom of table$/;"	e
+PS_LOOKUP_PAST_TOP	include/psLookupTable.h	/^    PS_LOOKUP_PAST_TOP            = 0x0101,        \/\/\/< Lookup off top of table$/;"	e
+PS_LOOKUP_PAST_TOP	src/fileUtils/psLookupTable.h	/^    PS_LOOKUP_PAST_TOP            = 0x0101,        \/\/\/< Lookup off top of table$/;"	e
+PS_LOOKUP_SUCCESS	include/psLookupTable.h	/^    PS_LOOKUP_SUCCESS             = 0x0000,        \/\/\/< Table lookup succeeded$/;"	e
+PS_LOOKUP_SUCCESS	src/fileUtils/psLookupTable.h	/^    PS_LOOKUP_SUCCESS             = 0x0000,        \/\/\/< Table lookup succeeded$/;"	e
+PS_MAX	include/psConstants.h	/^#define PS_MAX(/;"	d
+PS_MAX	src/dataManip/psConstants.h	/^#define PS_MAX(/;"	d
+PS_MAX_C32	include/psType.h	/^#define PS_MAX_C32 /;"	d
+PS_MAX_C32	src/sysUtils/psType.h	/^#define PS_MAX_C32 /;"	d
+PS_MAX_C64	include/psType.h	/^#define PS_MAX_C64 /;"	d
+PS_MAX_C64	src/sysUtils/psType.h	/^#define PS_MAX_C64 /;"	d
+PS_MAX_F32	include/psType.h	/^#define PS_MAX_F32 /;"	d
+PS_MAX_F32	src/sysUtils/psType.h	/^#define PS_MAX_F32 /;"	d
+PS_MAX_F64	include/psType.h	/^#define PS_MAX_F64 /;"	d
+PS_MAX_F64	src/sysUtils/psType.h	/^#define PS_MAX_F64 /;"	d
+PS_MAX_LMM_ITERATIONS	include/psConstants.h	/^#define PS_MAX_LMM_ITERATIONS /;"	d
+PS_MAX_LMM_ITERATIONS	src/dataManip/psConstants.h	/^#define PS_MAX_LMM_ITERATIONS /;"	d
+PS_MAX_MINIMIZE_ITERATIONS	include/psConstants.h	/^#define PS_MAX_MINIMIZE_ITERATIONS /;"	d
+PS_MAX_MINIMIZE_ITERATIONS	src/dataManip/psConstants.h	/^#define PS_MAX_MINIMIZE_ITERATIONS /;"	d
+PS_MAX_S16	include/psType.h	/^#define PS_MAX_S16 /;"	d
+PS_MAX_S16	src/sysUtils/psType.h	/^#define PS_MAX_S16 /;"	d
+PS_MAX_S32	include/psType.h	/^#define PS_MAX_S32 /;"	d
+PS_MAX_S32	src/sysUtils/psType.h	/^#define PS_MAX_S32 /;"	d
+PS_MAX_S64	include/psType.h	/^#define PS_MAX_S64 /;"	d
+PS_MAX_S64	src/sysUtils/psType.h	/^#define PS_MAX_S64 /;"	d
+PS_MAX_S8	include/psType.h	/^#define PS_MAX_S8 /;"	d
+PS_MAX_S8	src/sysUtils/psType.h	/^#define PS_MAX_S8 /;"	d
+PS_MAX_U16	include/psType.h	/^#define PS_MAX_U16 /;"	d
+PS_MAX_U16	src/sysUtils/psType.h	/^#define PS_MAX_U16 /;"	d
+PS_MAX_U32	include/psType.h	/^#define PS_MAX_U32 /;"	d
+PS_MAX_U32	src/sysUtils/psType.h	/^#define PS_MAX_U32 /;"	d
+PS_MAX_U64	include/psType.h	/^#define PS_MAX_U64 /;"	d
+PS_MAX_U64	src/sysUtils/psType.h	/^#define PS_MAX_U64 /;"	d
+PS_MAX_U8	include/psType.h	/^#define PS_MAX_U8 /;"	d
+PS_MAX_U8	src/sysUtils/psType.h	/^#define PS_MAX_U8 /;"	d
+PS_MEMORY_H	include/psMemory.h	/^#define PS_MEMORY_H$/;"	d
+PS_MEMORY_H	src/sysUtils/psMemory.h	/^#define PS_MEMORY_H$/;"	d
+PS_METADATAIO_H	include/psMetadataIO.h	/^#define PS_METADATAIO_H$/;"	d
+PS_METADATAIO_H	src/astronomy/psMetadataIO.h	/^#define PS_METADATAIO_H$/;"	d
+PS_METADATA_H	include/psMetadata.h	/^#define PS_METADATA_H$/;"	d
+PS_METADATA_H	src/astronomy/psMetadata.h	/^#define PS_METADATA_H$/;"	d
+PS_META_ASTROM	include/psMetadata.h	/^    PS_META_ASTROM,                    \/\/\/< Astrometric coefficients (Stored as item.data.V).$/;"	e
+PS_META_ASTROM	src/astronomy/psMetadata.h	/^    PS_META_ASTROM,                    \/\/\/< Astrometric coefficients (Stored as item.data.V).$/;"	e
+PS_META_HASH	include/psMetadata.h	/^    PS_META_HASH,                      \/\/\/< Hash data (Stored as item.data.V).$/;"	e
+PS_META_HASH	src/astronomy/psMetadata.h	/^    PS_META_HASH,                      \/\/\/< Hash data (Stored as item.data.V).$/;"	e
+PS_META_IMG	include/psMetadata.h	/^    PS_META_IMG,                       \/\/\/< Image data (Stored as item.data.V).$/;"	e
+PS_META_IMG	src/astronomy/psMetadata.h	/^    PS_META_IMG,                       \/\/\/< Image data (Stored as item.data.V).$/;"	e
+PS_META_JPEG	include/psMetadata.h	/^    PS_META_JPEG,                      \/\/\/< JPEG data (Stored as item.data.V).$/;"	e
+PS_META_JPEG	src/astronomy/psMetadata.h	/^    PS_META_JPEG,                      \/\/\/< JPEG data (Stored as item.data.V).$/;"	e
+PS_META_LIST	include/psMetadata.h	/^    PS_META_LIST,                      \/\/\/< List data (Stored as item.data.list).$/;"	e
+PS_META_LIST	src/astronomy/psMetadata.h	/^    PS_META_LIST,                      \/\/\/< List data (Stored as item.data.list).$/;"	e
+PS_META_LOOKUPTABLE	include/psMetadata.h	/^    PS_META_LOOKUPTABLE,               \/\/\/< Lookup table data (Stored as item.data.V).$/;"	e
+PS_META_LOOKUPTABLE	src/astronomy/psMetadata.h	/^    PS_META_LOOKUPTABLE,               \/\/\/< Lookup table data (Stored as item.data.V).$/;"	e
+PS_META_NTYPE	include/psMetadata.h	/^    PS_META_NTYPE                      \/\/\/< Number of types. Must be last.$/;"	e
+PS_META_NTYPE	src/astronomy/psMetadata.h	/^    PS_META_NTYPE                      \/\/\/< Number of types. Must be last.$/;"	e
+PS_META_PNG	include/psMetadata.h	/^    PS_META_PNG,                       \/\/\/< PNG data (Stored as item.data.V).$/;"	e
+PS_META_PNG	src/astronomy/psMetadata.h	/^    PS_META_PNG,                       \/\/\/< PNG data (Stored as item.data.V).$/;"	e
+PS_META_PRIMITIVE	include/psMetadata.h	/^    PS_META_PRIMITIVE,                 \/\/\/< Primitive data.$/;"	e
+PS_META_PRIMITIVE	src/astronomy/psMetadata.h	/^    PS_META_PRIMITIVE,                 \/\/\/< Primitive data.$/;"	e
+PS_META_STR	include/psMetadata.h	/^    PS_META_STR,                       \/\/\/< String data (Stored as item.data.V).$/;"	e
+PS_META_STR	src/astronomy/psMetadata.h	/^    PS_META_STR,                       \/\/\/< String data (Stored as item.data.V).$/;"	e
+PS_META_UNKNOWN	include/psMetadata.h	/^    PS_META_UNKNOWN,                   \/\/\/< Other data (Stored as item.data.V).$/;"	e
+PS_META_UNKNOWN	src/astronomy/psMetadata.h	/^    PS_META_UNKNOWN,                   \/\/\/< Other data (Stored as item.data.V).$/;"	e
+PS_META_VEC	include/psMetadata.h	/^    PS_META_VEC,                       \/\/\/< Vector data (Stored as item.data.V).$/;"	e
+PS_META_VEC	src/astronomy/psMetadata.h	/^    PS_META_VEC,                       \/\/\/< Vector data (Stored as item.data.V).$/;"	e
+PS_MIN	include/psConstants.h	/^#define PS_MIN(/;"	d
+PS_MIN	src/dataManip/psConstants.h	/^#define PS_MIN(/;"	d
+PS_MINIMIZE_H	include/psMinimize.h	/^#define PS_MINIMIZE_H$/;"	d
+PS_MINIMIZE_H	src/dataManip/psMinimize.h	/^#define PS_MINIMIZE_H$/;"	d
+PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE	src/dataManip/psMinimize.c	/^#define PS_MINIMIZE_POWELL_LINEMIN_ERROR_TOLERANCE /;"	d	file:
+PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS	src/dataManip/psMinimize.c	/^#define PS_MINIMIZE_POWELL_LINEMIN_MAX_ITERATIONS /;"	d	file:
+PS_MIN_C32	include/psType.h	/^#define PS_MIN_C32 /;"	d
+PS_MIN_C32	src/sysUtils/psType.h	/^#define PS_MIN_C32 /;"	d
+PS_MIN_C64	include/psType.h	/^#define PS_MIN_C64 /;"	d
+PS_MIN_C64	src/sysUtils/psType.h	/^#define PS_MIN_C64 /;"	d
+PS_MIN_F32	include/psType.h	/^#define PS_MIN_F32 /;"	d
+PS_MIN_F32	src/sysUtils/psType.h	/^#define PS_MIN_F32 /;"	d
+PS_MIN_F64	include/psType.h	/^#define PS_MIN_F64 /;"	d
+PS_MIN_F64	src/sysUtils/psType.h	/^#define PS_MIN_F64 /;"	d
+PS_MIN_S16	include/psType.h	/^#define PS_MIN_S16 /;"	d
+PS_MIN_S16	src/sysUtils/psType.h	/^#define PS_MIN_S16 /;"	d
+PS_MIN_S32	include/psType.h	/^#define PS_MIN_S32 /;"	d
+PS_MIN_S32	src/sysUtils/psType.h	/^#define PS_MIN_S32 /;"	d
+PS_MIN_S64	include/psType.h	/^#define PS_MIN_S64 /;"	d
+PS_MIN_S64	src/sysUtils/psType.h	/^#define PS_MIN_S64 /;"	d
+PS_MIN_S8	include/psType.h	/^#define PS_MIN_S8 /;"	d
+PS_MIN_S8	src/sysUtils/psType.h	/^#define PS_MIN_S8 /;"	d
+PS_MIN_U16	include/psType.h	/^#define PS_MIN_U16 /;"	d
+PS_MIN_U16	src/sysUtils/psType.h	/^#define PS_MIN_U16 /;"	d
+PS_MIN_U32	include/psType.h	/^#define PS_MIN_U32 /;"	d
+PS_MIN_U32	src/sysUtils/psType.h	/^#define PS_MIN_U32 /;"	d
+PS_MIN_U64	include/psType.h	/^#define PS_MIN_U64 /;"	d
+PS_MIN_U64	src/sysUtils/psType.h	/^#define PS_MIN_U64 /;"	d
+PS_MIN_U8	include/psType.h	/^#define PS_MIN_U8 /;"	d
+PS_MIN_U8	src/sysUtils/psType.h	/^#define PS_MIN_U8 /;"	d
+PS_ONE	include/psConstants.h	/^#define PS_ONE /;"	d
+PS_ONE	src/dataManip/psConstants.h	/^#define PS_ONE /;"	d
+PS_PARSE_ERROR_GENERAL	include/psLookupTable.h	/^    PS_PARSE_ERROR_GENERAL        = 0x0104         \/\/\/< Any other type of lookup error$/;"	e
+PS_PARSE_ERROR_GENERAL	src/fileUtils/psLookupTable.h	/^    PS_PARSE_ERROR_GENERAL        = 0x0104         \/\/\/< Any other type of lookup error$/;"	e
+PS_PARSE_ERROR_TYPE	include/psLookupTable.h	/^    PS_PARSE_ERROR_TYPE           = 0x0101,        \/\/\/< Error parsing type$/;"	e
+PS_PARSE_ERROR_TYPE	src/fileUtils/psLookupTable.h	/^    PS_PARSE_ERROR_TYPE           = 0x0101,        \/\/\/< Error parsing type$/;"	e
+PS_PARSE_ERROR_VALUE	include/psLookupTable.h	/^    PS_PARSE_ERROR_VALUE          = 0x0102,        \/\/\/< Error parsing numerical value$/;"	e
+PS_PARSE_ERROR_VALUE	src/fileUtils/psLookupTable.h	/^    PS_PARSE_ERROR_VALUE          = 0x0102,        \/\/\/< Error parsing numerical value$/;"	e
+PS_PARSE_SUCCESS	include/psLookupTable.h	/^    PS_PARSE_SUCCESS              = 0x0000,        \/\/\/< Table lookup succeeded$/;"	e
+PS_PARSE_SUCCESS	src/fileUtils/psLookupTable.h	/^    PS_PARSE_SUCCESS              = 0x0000,        \/\/\/< Table lookup succeeded$/;"	e
+PS_PHOTOMETRIC_H	include/psPhotometry.h	/^#define PS_PHOTOMETRIC_H$/;"	d
+PS_PHOTOMETRIC_H	src/astronomy/psPhotometry.h	/^#define PS_PHOTOMETRIC_H$/;"	d
+PS_POLYNOMIAL_CHEB	include/psFunctions.h	/^    PS_POLYNOMIAL_CHEB                 \/\/\/< Chebyshev Polynomial$/;"	e
+PS_POLYNOMIAL_CHEB	src/dataManip/psFunctions.h	/^    PS_POLYNOMIAL_CHEB                 \/\/\/< Chebyshev Polynomial$/;"	e
+PS_POLYNOMIAL_ORD	include/psFunctions.h	/^    PS_POLYNOMIAL_ORD,                 \/\/\/< Ordinary Polynomial$/;"	e
+PS_POLYNOMIAL_ORD	src/dataManip/psFunctions.h	/^    PS_POLYNOMIAL_ORD,                 \/\/\/< Ordinary Polynomial$/;"	e
+PS_POLY_1D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_1D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_1D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_1D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_1D_D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_1D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_1D_D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_1D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_2D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_2D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_2D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_2D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_2D_D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_2D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_2D_D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_2D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_3D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_3D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_3D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_3D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_3D_D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_3D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_3D_D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_3D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_4D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_4D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_4D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_4D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_4D_D_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_POLY_4D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_4D_D_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_POLY_4D_D_DECLARE_ALLOC_STATIC(/;"	d
+PS_POLY_CHECK_NULL	include/psConstants.h	/^#define PS_POLY_CHECK_NULL(/;"	d
+PS_POLY_CHECK_NULL	src/dataManip/psConstants.h	/^#define PS_POLY_CHECK_NULL(/;"	d
+PS_POLY_CHECK_TYPE	include/psConstants.h	/^#define PS_POLY_CHECK_TYPE(/;"	d
+PS_POLY_CHECK_TYPE	src/dataManip/psConstants.h	/^#define PS_POLY_CHECK_TYPE(/;"	d
+PS_POLY_MEDIAN_MAX_ITERATIONS	src/dataManip/psStats.c	/^#define PS_POLY_MEDIAN_MAX_ITERATIONS /;"	d	file:
+PS_PROJ_AIT	include/psCoord.h	/^    PS_PROJ_AIT,                \/\/\/< Aitoff projection$/;"	e
+PS_PROJ_AIT	src/astronomy/psCoord.h	/^    PS_PROJ_AIT,                \/\/\/< Aitoff projection$/;"	e
+PS_PROJ_CAR	include/psCoord.h	/^    PS_PROJ_CAR,                \/\/\/< CAR projection$/;"	e
+PS_PROJ_CAR	src/astronomy/psCoord.h	/^    PS_PROJ_CAR,                \/\/\/< CAR projection$/;"	e
+PS_PROJ_GLS	include/psCoord.h	/^    PS_PROJ_GLS,                \/\/\/< GLS projection$/;"	e
+PS_PROJ_GLS	src/astronomy/psCoord.h	/^    PS_PROJ_GLS,                \/\/\/< GLS projection$/;"	e
+PS_PROJ_MER	include/psCoord.h	/^    PS_PROJ_MER,                \/\/\/< MER projection$/;"	e
+PS_PROJ_MER	src/astronomy/psCoord.h	/^    PS_PROJ_MER,                \/\/\/< MER projection$/;"	e
+PS_PROJ_NTYPE	include/psCoord.h	/^    PS_PROJ_NTYPE               \/\/\/< Number of types; must be last.$/;"	e
+PS_PROJ_NTYPE	src/astronomy/psCoord.h	/^    PS_PROJ_NTYPE               \/\/\/< Number of types; must be last.$/;"	e
+PS_PROJ_PAR	include/psCoord.h	/^    PS_PROJ_PAR,                \/\/\/< Par projection$/;"	e
+PS_PROJ_PAR	src/astronomy/psCoord.h	/^    PS_PROJ_PAR,                \/\/\/< Par projection$/;"	e
+PS_PROJ_SIN	include/psCoord.h	/^    PS_PROJ_SIN,                \/\/\/< Sine projection$/;"	e
+PS_PROJ_SIN	src/astronomy/psCoord.h	/^    PS_PROJ_SIN,                \/\/\/< Sine projection$/;"	e
+PS_PROJ_TAN	include/psCoord.h	/^    PS_PROJ_TAN,                \/\/\/< Tangent projection$/;"	e
+PS_PROJ_TAN	src/astronomy/psCoord.h	/^    PS_PROJ_TAN,                \/\/\/< Tangent projection$/;"	e
+PS_PTR_CHECK_DIMEN	include/psConstants.h	/^#define PS_PTR_CHECK_DIMEN(/;"	d
+PS_PTR_CHECK_DIMEN	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_DIMEN(/;"	d
+PS_PTR_CHECK_DIMEN_GENERAL	include/psConstants.h	/^#define PS_PTR_CHECK_DIMEN_GENERAL(/;"	d
+PS_PTR_CHECK_DIMEN_GENERAL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_DIMEN_GENERAL(/;"	d
+PS_PTR_CHECK_DIMEN_GENERAL_NOT	include/psConstants.h	/^#define PS_PTR_CHECK_DIMEN_GENERAL_NOT(/;"	d
+PS_PTR_CHECK_DIMEN_GENERAL_NOT	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_DIMEN_GENERAL_NOT(/;"	d
+PS_PTR_CHECK_NULL	include/psConstants.h	/^#define PS_PTR_CHECK_NULL(/;"	d
+PS_PTR_CHECK_NULL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_NULL(/;"	d
+PS_PTR_CHECK_NULL_GENERAL	include/psConstants.h	/^#define PS_PTR_CHECK_NULL_GENERAL(/;"	d
+PS_PTR_CHECK_NULL_GENERAL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_NULL_GENERAL(/;"	d
+PS_PTR_CHECK_SIZE_EQUAL	include/psConstants.h	/^#define PS_PTR_CHECK_SIZE_EQUAL(/;"	d
+PS_PTR_CHECK_SIZE_EQUAL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_SIZE_EQUAL(/;"	d
+PS_PTR_CHECK_TYPE	include/psConstants.h	/^#define PS_PTR_CHECK_TYPE(/;"	d
+PS_PTR_CHECK_TYPE	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_TYPE(/;"	d
+PS_PTR_CHECK_TYPE_EQUAL	include/psConstants.h	/^#define PS_PTR_CHECK_TYPE_EQUAL(/;"	d
+PS_PTR_CHECK_TYPE_EQUAL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_TYPE_EQUAL(/;"	d
+PS_PTR_CHECK_TYPE_EQUAL_GENERAL	include/psConstants.h	/^#define PS_PTR_CHECK_TYPE_EQUAL_GENERAL(/;"	d
+PS_PTR_CHECK_TYPE_EQUAL_GENERAL	src/dataManip/psConstants.h	/^#define PS_PTR_CHECK_TYPE_EQUAL_GENERAL(/;"	d
+PS_PWD	src/dataManip/psMinimize.c	/^#define PS_PWD /;"	d	file:
+PS_RADIAN	include/psCoord.h	/^    PS_RADIAN                   \/\/\/< Radians$/;"	e
+PS_RADIAN	src/astronomy/psCoord.h	/^    PS_RADIAN                   \/\/\/< Radians$/;"	e
+PS_RANDOM_H	include/psRandom.h	/^#define PS_RANDOM_H$/;"	d
+PS_RANDOM_H	src/dataManip/psRandom.h	/^#define PS_RANDOM_H$/;"	d
+PS_RANDOM_TAUS	include/psRandom.h	/^    PS_RANDOM_TAUS    \/\/\/< A maximally equidistributed combined Tausworthe generator.$/;"	e
+PS_RANDOM_TAUS	src/dataManip/psRandom.h	/^    PS_RANDOM_TAUS    \/\/\/< A maximally equidistributed combined Tausworthe generator.$/;"	e
+PS_READOUT_CHECK_EMPTY	include/psConstants.h	/^#define PS_READOUT_CHECK_EMPTY(/;"	d
+PS_READOUT_CHECK_EMPTY	src/dataManip/psConstants.h	/^#define PS_READOUT_CHECK_EMPTY(/;"	d
+PS_READOUT_CHECK_NULL	include/psConstants.h	/^#define PS_READOUT_CHECK_NULL(/;"	d
+PS_READOUT_CHECK_NULL	src/dataManip/psConstants.h	/^#define PS_READOUT_CHECK_NULL(/;"	d
+PS_READOUT_CHECK_TYPE	include/psConstants.h	/^#define PS_READOUT_CHECK_TYPE(/;"	d
+PS_READOUT_CHECK_TYPE	src/dataManip/psConstants.h	/^#define PS_READOUT_CHECK_TYPE(/;"	d
+PS_RIGHT_SPLINE_DERIV	include/psConstants.h	/^#define PS_RIGHT_SPLINE_DERIV /;"	d
+PS_RIGHT_SPLINE_DERIV	src/dataManip/psConstants.h	/^#define PS_RIGHT_SPLINE_DERIV /;"	d
+PS_SCALAR_H	include/psScalar.h	/^#define PS_SCALAR_H$/;"	d
+PS_SCALAR_H	src/collections/psScalar.h	/^#define PS_SCALAR_H$/;"	d
+PS_SEG	src/dataManip/psMinimize.c	/^#define PS_SEG /;"	d	file:
+PS_SET_BADPIXEL	include/psType.h	/^#define PS_SET_BADPIXEL(/;"	d
+PS_SET_BADPIXEL	src/sysUtils/psType.h	/^#define PS_SET_BADPIXEL(/;"	d
+PS_SPHERICAL	include/psCoord.h	/^    PS_SPHERICAL,               \/\/\/< offset corresponds to an angular offset$/;"	e
+PS_SPHERICAL	src/astronomy/psCoord.h	/^    PS_SPHERICAL,               \/\/\/< offset corresponds to an angular offset$/;"	e
+PS_SQR	include/psConstants.h	/^#define PS_SQR(/;"	d
+PS_SQR	src/dataManip/psConstants.h	/^#define PS_SQR(/;"	d
+PS_SQRT_F32	include/psConstants.h	/^#define PS_SQRT_F32(/;"	d
+PS_SQRT_F32	src/dataManip/psConstants.h	/^#define PS_SQRT_F32(/;"	d
+PS_STATS_H	include/psStats.h	/^#define PS_STATS_H$/;"	d
+PS_STATS_H	src/dataManip/psStats.h	/^#define PS_STATS_H$/;"	d
+PS_STAT_CLIPPED_MEAN	include/psStats.h	/^    PS_STAT_CLIPPED_MEAN = 0x000200,$/;"	e
+PS_STAT_CLIPPED_MEAN	src/dataManip/psStats.h	/^    PS_STAT_CLIPPED_MEAN = 0x000200,$/;"	e
+PS_STAT_CLIPPED_STDEV	include/psStats.h	/^    PS_STAT_CLIPPED_STDEV = 0x000400,$/;"	e
+PS_STAT_CLIPPED_STDEV	src/dataManip/psStats.h	/^    PS_STAT_CLIPPED_STDEV = 0x000400,$/;"	e
+PS_STAT_MAX	include/psStats.h	/^    PS_STAT_MAX =  0x000800,$/;"	e
+PS_STAT_MAX	src/dataManip/psStats.h	/^    PS_STAT_MAX =  0x000800,$/;"	e
+PS_STAT_MIN	include/psStats.h	/^    PS_STAT_MIN =  0x001000,$/;"	e
+PS_STAT_MIN	src/dataManip/psStats.h	/^    PS_STAT_MIN =  0x001000,$/;"	e
+PS_STAT_ROBUST_FOR_SAMPLE	include/psStats.h	/^    PS_STAT_ROBUST_FOR_SAMPLE = 0x008000$/;"	e
+PS_STAT_ROBUST_FOR_SAMPLE	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_FOR_SAMPLE = 0x008000$/;"	e
+PS_STAT_ROBUST_MEAN	include/psStats.h	/^    PS_STAT_ROBUST_MEAN = 0x000010,$/;"	e
+PS_STAT_ROBUST_MEAN	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_MEAN = 0x000010,$/;"	e
+PS_STAT_ROBUST_MEDIAN	include/psStats.h	/^    PS_STAT_ROBUST_MEDIAN = 0x000020,$/;"	e
+PS_STAT_ROBUST_MEDIAN	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_MEDIAN = 0x000020,$/;"	e
+PS_STAT_ROBUST_MODE	include/psStats.h	/^    PS_STAT_ROBUST_MODE = 0x000040,$/;"	e
+PS_STAT_ROBUST_MODE	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_MODE = 0x000040,$/;"	e
+PS_STAT_ROBUST_QUARTILE	include/psStats.h	/^    PS_STAT_ROBUST_QUARTILE = 0x000100,$/;"	e
+PS_STAT_ROBUST_QUARTILE	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_QUARTILE = 0x000100,$/;"	e
+PS_STAT_ROBUST_STDEV	include/psStats.h	/^    PS_STAT_ROBUST_STDEV = 0x000080,$/;"	e
+PS_STAT_ROBUST_STDEV	src/dataManip/psStats.h	/^    PS_STAT_ROBUST_STDEV = 0x000080,$/;"	e
+PS_STAT_SAMPLE_MEAN	include/psStats.h	/^    PS_STAT_SAMPLE_MEAN = 0x000001,$/;"	e
+PS_STAT_SAMPLE_MEAN	src/dataManip/psStats.h	/^    PS_STAT_SAMPLE_MEAN = 0x000001,$/;"	e
+PS_STAT_SAMPLE_MEDIAN	include/psStats.h	/^    PS_STAT_SAMPLE_MEDIAN = 0x000002,$/;"	e
+PS_STAT_SAMPLE_MEDIAN	src/dataManip/psStats.h	/^    PS_STAT_SAMPLE_MEDIAN = 0x000002,$/;"	e
+PS_STAT_SAMPLE_QUARTILE	include/psStats.h	/^    PS_STAT_SAMPLE_QUARTILE = 0x000008,$/;"	e
+PS_STAT_SAMPLE_QUARTILE	src/dataManip/psStats.h	/^    PS_STAT_SAMPLE_QUARTILE = 0x000008,$/;"	e
+PS_STAT_SAMPLE_STDEV	include/psStats.h	/^    PS_STAT_SAMPLE_STDEV = 0x000004,$/;"	e
+PS_STAT_SAMPLE_STDEV	src/dataManip/psStats.h	/^    PS_STAT_SAMPLE_STDEV = 0x000004,$/;"	e
+PS_STAT_USE_BINSIZE	include/psStats.h	/^    PS_STAT_USE_BINSIZE = 0x004000,$/;"	e
+PS_STAT_USE_BINSIZE	src/dataManip/psStats.h	/^    PS_STAT_USE_BINSIZE = 0x004000,$/;"	e
+PS_STAT_USE_RANGE	include/psStats.h	/^    PS_STAT_USE_RANGE =  0x002000,$/;"	e
+PS_STAT_USE_RANGE	src/dataManip/psStats.h	/^    PS_STAT_USE_RANGE =  0x002000,$/;"	e
+PS_STRING	include/psString.h	/^#define PS_STRING(/;"	d
+PS_STRING	src/sysUtils/psString.h	/^#define PS_STRING(/;"	d
+PS_STRING_H	include/psString.h	/^#define PS_STRING_H$/;"	d
+PS_STRING_H	src/sysUtils/psString.h	/^#define PS_STRING_H$/;"	d
+PS_SYSUTILS_ERRORS_H	src/sysUtils/psSysUtilsErrors.h	/^#define PS_SYSUTILS_ERRORS_H$/;"	d
+PS_THE_OTHER_DEFAULT_TRACE_LEVEL	include/psTrace.h	/^#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL /;"	d
+PS_THE_OTHER_DEFAULT_TRACE_LEVEL	src/sysUtils/psTrace.h	/^#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL /;"	d
+PS_TIME_TAI	include/psTime.h	/^    PS_TIME_TAI,        \/\/\/< Temps Atomique International (TAI) time (time with leapseconds).$/;"	e
+PS_TIME_TAI	src/astronomy/psTime.h	/^    PS_TIME_TAI,        \/\/\/< Temps Atomique International (TAI) time (time with leapseconds).$/;"	e
+PS_TIME_UTC	include/psTime.h	/^    PS_TIME_UTC,        \/\/\/< Universal Time Coordinated (UTC) time (time without leapseconds).$/;"	e
+PS_TIME_UTC	src/astronomy/psTime.h	/^    PS_TIME_UTC,        \/\/\/< Universal Time Coordinated (UTC) time (time without leapseconds).$/;"	e
+PS_TRACE_H	include/psTrace.h	/^#define PS_TRACE_H /;"	d
+PS_TRACE_H	src/sysUtils/psTrace.h	/^#define PS_TRACE_H /;"	d
+PS_TYPE_BOOL	include/psType.h	/^    PS_TYPE_BOOL = 0x1301,             \/\/\/< Boolean.$/;"	e
+PS_TYPE_BOOL	src/sysUtils/psType.h	/^    PS_TYPE_BOOL = 0x1301,             \/\/\/< Boolean.$/;"	e
+PS_TYPE_BOOL_NAME	include/psType.h	/^#define PS_TYPE_BOOL_NAME /;"	d
+PS_TYPE_BOOL_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_BOOL_NAME /;"	d
+PS_TYPE_C32	include/psType.h	/^    PS_TYPE_C32  = 0x0808,             \/\/\/< Complex numbers consisting of single-precision floating point.$/;"	e
+PS_TYPE_C32	src/sysUtils/psType.h	/^    PS_TYPE_C32  = 0x0808,             \/\/\/< Complex numbers consisting of single-precision floating point.$/;"	e
+PS_TYPE_C32_NAME	include/psType.h	/^#define PS_TYPE_C32_NAME /;"	d
+PS_TYPE_C32_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_C32_NAME /;"	d
+PS_TYPE_C64	include/psType.h	/^    PS_TYPE_C64  = 0x0810,             \/\/\/< Complex numbers consisting of double-precision floating point.$/;"	e
+PS_TYPE_C64	src/sysUtils/psType.h	/^    PS_TYPE_C64  = 0x0810,             \/\/\/< Complex numbers consisting of double-precision floating point.$/;"	e
+PS_TYPE_C64_NAME	include/psType.h	/^#define PS_TYPE_C64_NAME /;"	d
+PS_TYPE_C64_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_C64_NAME /;"	d
+PS_TYPE_F32	include/psType.h	/^    PS_TYPE_F32  = 0x0404,             \/\/\/< Single-precision Floating point.$/;"	e
+PS_TYPE_F32	src/sysUtils/psType.h	/^    PS_TYPE_F32  = 0x0404,             \/\/\/< Single-precision Floating point.$/;"	e
+PS_TYPE_F32_NAME	include/psType.h	/^#define PS_TYPE_F32_NAME /;"	d
+PS_TYPE_F32_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_F32_NAME /;"	d
+PS_TYPE_F64	include/psType.h	/^    PS_TYPE_F64  = 0x0408,             \/\/\/< Double-precision floating point.$/;"	e
+PS_TYPE_F64	src/sysUtils/psType.h	/^    PS_TYPE_F64  = 0x0408,             \/\/\/< Double-precision floating point.$/;"	e
+PS_TYPE_F64_NAME	include/psType.h	/^#define PS_TYPE_F64_NAME /;"	d
+PS_TYPE_F64_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_F64_NAME /;"	d
+PS_TYPE_H	include/psType.h	/^#define PS_TYPE_H$/;"	d
+PS_TYPE_H	src/sysUtils/psType.h	/^#define PS_TYPE_H$/;"	d
+PS_TYPE_KERNEL	include/psImageConvolve.h	/^#define PS_TYPE_KERNEL /;"	d
+PS_TYPE_KERNEL	src/image/psImageConvolve.h	/^#define PS_TYPE_KERNEL /;"	d
+PS_TYPE_KERNEL_DATA	include/psImageConvolve.h	/^#define PS_TYPE_KERNEL_DATA /;"	d
+PS_TYPE_KERNEL_DATA	src/image/psImageConvolve.h	/^#define PS_TYPE_KERNEL_DATA /;"	d
+PS_TYPE_KERNEL_NAME	include/psImageConvolve.h	/^#define PS_TYPE_KERNEL_NAME /;"	d
+PS_TYPE_KERNEL_NAME	src/image/psImageConvolve.h	/^#define PS_TYPE_KERNEL_NAME /;"	d
+PS_TYPE_MASK	include/psType.h	/^#define PS_TYPE_MASK /;"	d
+PS_TYPE_MASK	src/sysUtils/psType.h	/^#define PS_TYPE_MASK /;"	d
+PS_TYPE_MASK_DATA	include/psType.h	/^#define PS_TYPE_MASK_DATA /;"	d
+PS_TYPE_MASK_DATA	src/sysUtils/psType.h	/^#define PS_TYPE_MASK_DATA /;"	d
+PS_TYPE_MASK_NAME	include/psType.h	/^#define PS_TYPE_MASK_NAME /;"	d
+PS_TYPE_MASK_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_MASK_NAME /;"	d
+PS_TYPE_NAME	include/psType.h	/^#define PS_TYPE_NAME(/;"	d
+PS_TYPE_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_NAME(/;"	d
+PS_TYPE_PTR	include/psType.h	/^    PS_TYPE_PTR  = 0x0000              \/\/\/< Something else that's not supported for arithmetic.$/;"	e
+PS_TYPE_PTR	src/sysUtils/psType.h	/^    PS_TYPE_PTR  = 0x0000              \/\/\/< Something else that's not supported for arithmetic.$/;"	e
+PS_TYPE_PTR_NAME	include/psType.h	/^#define PS_TYPE_PTR_NAME /;"	d
+PS_TYPE_PTR_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_PTR_NAME /;"	d
+PS_TYPE_S16	include/psType.h	/^    PS_TYPE_S16  = 0x0102,             \/\/\/< Short integer.$/;"	e
+PS_TYPE_S16	src/sysUtils/psType.h	/^    PS_TYPE_S16  = 0x0102,             \/\/\/< Short integer.$/;"	e
+PS_TYPE_S16_NAME	include/psType.h	/^#define PS_TYPE_S16_NAME /;"	d
+PS_TYPE_S16_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_S16_NAME /;"	d
+PS_TYPE_S32	include/psType.h	/^    PS_TYPE_S32  = 0x0104,             \/\/\/< Integer.$/;"	e
+PS_TYPE_S32	src/sysUtils/psType.h	/^    PS_TYPE_S32  = 0x0104,             \/\/\/< Integer.$/;"	e
+PS_TYPE_S32_NAME	include/psType.h	/^#define PS_TYPE_S32_NAME /;"	d
+PS_TYPE_S32_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_S32_NAME /;"	d
+PS_TYPE_S64	include/psType.h	/^    PS_TYPE_S64  = 0x0108,             \/\/\/< Long integer.$/;"	e
+PS_TYPE_S64	src/sysUtils/psType.h	/^    PS_TYPE_S64  = 0x0108,             \/\/\/< Long integer.$/;"	e
+PS_TYPE_S64_NAME	include/psType.h	/^#define PS_TYPE_S64_NAME /;"	d
+PS_TYPE_S64_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_S64_NAME /;"	d
+PS_TYPE_S8	include/psType.h	/^    PS_TYPE_S8   = 0x0101,             \/\/\/< Character.$/;"	e
+PS_TYPE_S8	src/sysUtils/psType.h	/^    PS_TYPE_S8   = 0x0101,             \/\/\/< Character.$/;"	e
+PS_TYPE_S8_NAME	include/psType.h	/^#define PS_TYPE_S8_NAME /;"	d
+PS_TYPE_S8_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_S8_NAME /;"	d
+PS_TYPE_U16	include/psType.h	/^    PS_TYPE_U16  = 0x0302,             \/\/\/< Unsigned psS16 integer.$/;"	e
+PS_TYPE_U16	src/sysUtils/psType.h	/^    PS_TYPE_U16  = 0x0302,             \/\/\/< Unsigned psS16 integer.$/;"	e
+PS_TYPE_U16_NAME	include/psType.h	/^#define PS_TYPE_U16_NAME /;"	d
+PS_TYPE_U16_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_U16_NAME /;"	d
+PS_TYPE_U32	include/psType.h	/^    PS_TYPE_U32  = 0x0304,             \/\/\/< Unsigned integer.$/;"	e
+PS_TYPE_U32	src/sysUtils/psType.h	/^    PS_TYPE_U32  = 0x0304,             \/\/\/< Unsigned integer.$/;"	e
+PS_TYPE_U32_NAME	include/psType.h	/^#define PS_TYPE_U32_NAME /;"	d
+PS_TYPE_U32_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_U32_NAME /;"	d
+PS_TYPE_U64	include/psType.h	/^    PS_TYPE_U64  = 0x0308,             \/\/\/< Unsigned psS64 integer.$/;"	e
+PS_TYPE_U64	src/sysUtils/psType.h	/^    PS_TYPE_U64  = 0x0308,             \/\/\/< Unsigned psS64 integer.$/;"	e
+PS_TYPE_U64_NAME	include/psType.h	/^#define PS_TYPE_U64_NAME /;"	d
+PS_TYPE_U64_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_U64_NAME /;"	d
+PS_TYPE_U8	include/psType.h	/^    PS_TYPE_U8   = 0x0301,             \/\/\/< Unsigned character.$/;"	e
+PS_TYPE_U8	src/sysUtils/psType.h	/^    PS_TYPE_U8   = 0x0301,             \/\/\/< Unsigned character.$/;"	e
+PS_TYPE_U8_NAME	include/psType.h	/^#define PS_TYPE_U8_NAME /;"	d
+PS_TYPE_U8_NAME	src/sysUtils/psType.h	/^#define PS_TYPE_U8_NAME /;"	d
+PS_UNKNOWN_TRACE_LEVEL	include/psTrace.h	/^#define PS_UNKNOWN_TRACE_LEVEL /;"	d
+PS_UNKNOWN_TRACE_LEVEL	src/sysUtils/psTrace.h	/^#define PS_UNKNOWN_TRACE_LEVEL /;"	d
+PS_VECTOR_ADD_MULTIPLE	src/dataManip/psMinimize.c	/^#define PS_VECTOR_ADD_MULTIPLE(/;"	d	file:
+PS_VECTOR_CHECK_EMPTY	include/psConstants.h	/^#define PS_VECTOR_CHECK_EMPTY(/;"	d
+PS_VECTOR_CHECK_EMPTY	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_EMPTY(/;"	d
+PS_VECTOR_CHECK_NULL	include/psConstants.h	/^#define PS_VECTOR_CHECK_NULL(/;"	d
+PS_VECTOR_CHECK_NULL	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_NULL(/;"	d
+PS_VECTOR_CHECK_NULL_GENERAL	include/psConstants.h	/^#define PS_VECTOR_CHECK_NULL_GENERAL(/;"	d
+PS_VECTOR_CHECK_NULL_GENERAL	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_NULL_GENERAL(/;"	d
+PS_VECTOR_CHECK_SIZE_EQUAL	include/psConstants.h	/^#define PS_VECTOR_CHECK_SIZE_EQUAL(/;"	d
+PS_VECTOR_CHECK_SIZE_EQUAL	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_SIZE_EQUAL(/;"	d
+PS_VECTOR_CHECK_TYPE	include/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE(/;"	d
+PS_VECTOR_CHECK_TYPE	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE(/;"	d
+PS_VECTOR_CHECK_TYPE_EQUAL	include/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_EQUAL(/;"	d
+PS_VECTOR_CHECK_TYPE_EQUAL	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_EQUAL(/;"	d
+PS_VECTOR_CHECK_TYPE_F32_OR_F64	include/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_F32_OR_F64(/;"	d
+PS_VECTOR_CHECK_TYPE_F32_OR_F64	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_F32_OR_F64(/;"	d
+PS_VECTOR_CHECK_TYPE_S16_S32_F32	include/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_S16_S32_F32(/;"	d
+PS_VECTOR_CHECK_TYPE_S16_S32_F32	src/dataManip/psConstants.h	/^#define PS_VECTOR_CHECK_TYPE_S16_S32_F32(/;"	d
+PS_VECTOR_CONVERT_F32_TO_F64_STATIC	include/psConstants.h	/^#define PS_VECTOR_CONVERT_F32_TO_F64_STATIC(/;"	d
+PS_VECTOR_CONVERT_F32_TO_F64_STATIC	src/dataManip/psConstants.h	/^#define PS_VECTOR_CONVERT_F32_TO_F64_STATIC(/;"	d
+PS_VECTOR_CONVERT_F64_TO_F32_STATIC	include/psConstants.h	/^#define PS_VECTOR_CONVERT_F64_TO_F32_STATIC(/;"	d
+PS_VECTOR_CONVERT_F64_TO_F32_STATIC	src/dataManip/psConstants.h	/^#define PS_VECTOR_CONVERT_F64_TO_F32_STATIC(/;"	d
+PS_VECTOR_DECLARE_ALLOC_STATIC	include/psConstants.h	/^#define PS_VECTOR_DECLARE_ALLOC_STATIC(/;"	d
+PS_VECTOR_DECLARE_ALLOC_STATIC	src/dataManip/psConstants.h	/^#define PS_VECTOR_DECLARE_ALLOC_STATIC(/;"	d
+PS_VECTOR_F32_CHECK_ZERO_VECTOR	src/dataManip/psMinimize.c	/^#define PS_VECTOR_F32_CHECK_ZERO_VECTOR(/;"	d	file:
+PS_VECTOR_F32_TO_F64	include/psConstants.h	/^#define PS_VECTOR_F32_TO_F64(/;"	d
+PS_VECTOR_F32_TO_F64	src/dataManip/psConstants.h	/^#define PS_VECTOR_F32_TO_F64(/;"	d
+PS_VECTOR_F64_TO_F32	include/psConstants.h	/^#define PS_VECTOR_F64_TO_F32(/;"	d
+PS_VECTOR_F64_TO_F32	src/dataManip/psConstants.h	/^#define PS_VECTOR_F64_TO_F32(/;"	d
+PS_VECTOR_FFT_H	include/psVectorFFT.h	/^#define PS_VECTOR_FFT_H$/;"	d
+PS_VECTOR_FFT_H	src/dataManip/psVectorFFT.h	/^#define PS_VECTOR_FFT_H$/;"	d
+PS_VECTOR_GEN_STATIC_RECYCLED	include/psConstants.h	/^#define PS_VECTOR_GEN_STATIC_RECYCLED(/;"	d
+PS_VECTOR_GEN_STATIC_RECYCLED	src/dataManip/psConstants.h	/^#define PS_VECTOR_GEN_STATIC_RECYCLED(/;"	d
+PS_VECTOR_GEN_X_INDEX_STATIC_F32	include/psConstants.h	/^#define PS_VECTOR_GEN_X_INDEX_STATIC_F32(/;"	d
+PS_VECTOR_GEN_X_INDEX_STATIC_F32	src/dataManip/psConstants.h	/^#define PS_VECTOR_GEN_X_INDEX_STATIC_F32(/;"	d
+PS_VECTOR_GEN_X_INDEX_STATIC_F64	include/psConstants.h	/^#define PS_VECTOR_GEN_X_INDEX_STATIC_F64(/;"	d
+PS_VECTOR_GEN_X_INDEX_STATIC_F64	src/dataManip/psConstants.h	/^#define PS_VECTOR_GEN_X_INDEX_STATIC_F64(/;"	d
+PS_VECTOR_GEN_YERR_STATIC_F32	include/psConstants.h	/^#define PS_VECTOR_GEN_YERR_STATIC_F32(/;"	d
+PS_VECTOR_GEN_YERR_STATIC_F32	src/dataManip/psConstants.h	/^#define PS_VECTOR_GEN_YERR_STATIC_F32(/;"	d
+PS_VECTOR_GEN_YERR_STATIC_F64	include/psConstants.h	/^#define PS_VECTOR_GEN_YERR_STATIC_F64(/;"	d
+PS_VECTOR_GEN_YERR_STATIC_F64	src/dataManip/psConstants.h	/^#define PS_VECTOR_GEN_YERR_STATIC_F64(/;"	d
+PS_VECTOR_H	include/psVector.h	/^#define PS_VECTOR_H$/;"	d
+PS_VECTOR_H	src/collections/psVector.h	/^#define PS_VECTOR_H$/;"	d
+PS_VECTOR_PRINT	include/psConstants.h	/^#define PS_VECTOR_PRINT(/;"	d
+PS_VECTOR_PRINT	src/dataManip/psConstants.h	/^#define PS_VECTOR_PRINT(/;"	d
+PS_VECTOR_SET_F32	include/psConstants.h	/^#define PS_VECTOR_SET_F32(/;"	d
+PS_VECTOR_SET_F32	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_F32(/;"	d
+PS_VECTOR_SET_F64	include/psConstants.h	/^#define PS_VECTOR_SET_F64(/;"	d
+PS_VECTOR_SET_F64	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_F64(/;"	d
+PS_VECTOR_SET_S16	include/psConstants.h	/^#define PS_VECTOR_SET_S16(/;"	d
+PS_VECTOR_SET_S16	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_S16(/;"	d
+PS_VECTOR_SET_S32	include/psConstants.h	/^#define PS_VECTOR_SET_S32(/;"	d
+PS_VECTOR_SET_S32	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_S32(/;"	d
+PS_VECTOR_SET_S64	include/psConstants.h	/^#define PS_VECTOR_SET_S64(/;"	d
+PS_VECTOR_SET_S64	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_S64(/;"	d
+PS_VECTOR_SET_S8	include/psConstants.h	/^#define PS_VECTOR_SET_S8(/;"	d
+PS_VECTOR_SET_S8	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_S8(/;"	d
+PS_VECTOR_SET_U16	include/psConstants.h	/^#define PS_VECTOR_SET_U16(/;"	d
+PS_VECTOR_SET_U16	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_U16(/;"	d
+PS_VECTOR_SET_U32	include/psConstants.h	/^#define PS_VECTOR_SET_U32(/;"	d
+PS_VECTOR_SET_U32	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_U32(/;"	d
+PS_VECTOR_SET_U64	include/psConstants.h	/^#define PS_VECTOR_SET_U64(/;"	d
+PS_VECTOR_SET_U64	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_U64(/;"	d
+PS_VECTOR_SET_U8	include/psConstants.h	/^#define PS_VECTOR_SET_U8(/;"	d
+PS_VECTOR_SET_U8	src/dataManip/psConstants.h	/^#define PS_VECTOR_SET_U8(/;"	d
+PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR	src/dataManip/psMinimize.c	/^#define PS_VECTOR_WITH_MASK_F32_CHECK_ZERO_VECTOR(/;"	d	file:
+PTR	include/psImage.h	/^        psPtr** PTR;                   \/\/\/< Void pointers.$/;"	m	union:psImage::<anonymous>
+PTR	src/image/psImage.h	/^        psPtr** PTR;                   \/\/\/< Void pointers.$/;"	m	union:psImage::<anonymous>
+P_FFTW_PLAN_RIGOR	src/dataManip/psVectorFFT.c	/^#define P_FFTW_PLAN_RIGOR /;"	d	file:
+P_PS_LARGE_BLOCK_SIZE	src/sysUtils/psMemory.c	/^#define P_PS_LARGE_BLOCK_SIZE /;"	d	file:
+P_PS_MEMMAGIC	src/sysUtils/psMemory.c	/^#define P_PS_MEMMAGIC /;"	d	file:
+R	include/psCoord.h	/^    double R;                   \/\/\/< Coordinates of projection center$/;"	m
+R	src/astronomy/psCoord.h	/^    double R;                   \/\/\/< Coordinates of projection center$/;"	m
+R2D	src/dataManip/psMatrixVectorArithmetic.c	/^#define R2D /;"	d	file:
+R2DEG	src/astronomy/psTime.c	/^#define R2DEG /;"	d	file:
+RA	test/astronomy/tst_psAstrometry01.c	/^#define RA /;"	d	file:
+RAD_TO_ARCMIN	test/astronomy/tst_psCoord.c	/^#define RAD_TO_ARCMIN /;"	d	file:
+RAD_TO_ARCSEC	test/astronomy/tst_psCoord.c	/^#define RAD_TO_ARCSEC /;"	d	file:
+RAD_TO_DEG	src/astronomy/psCoord.c	/^#define RAD_TO_DEG(/;"	d	file:
+RAD_TO_DEG	test/astronomy/tst_psCoord.c	/^#define RAD_TO_DEG /;"	d	file:
+RAD_TO_MIN	src/astronomy/psCoord.c	/^#define RAD_TO_MIN(/;"	d	file:
+RAD_TO_SEC	src/astronomy/psCoord.c	/^#define RAD_TO_SEC(/;"	d	file:
+READOUT_NUM_COLS	test/astronomy/tst_psAstrometry01.c	/^#define READOUT_NUM_COLS /;"	d	file:
+READOUT_NUM_ROWS	test/astronomy/tst_psAstrometry01.c	/^#define READOUT_NUM_ROWS /;"	d	file:
+READ_TABLE_ROW_CASE	src/fileUtils/psFits.c	/^            #define READ_TABLE_ROW_CASE(/;"	d	file:
+RELATIVE_KERNEL_GENERATE_CASE	src/image/psImageConvolve.c	/^    #define RELATIVE_KERNEL_GENERATE_CASE(/;"	d	file:
+RETURN_FINAL_BRACKET	src/dataManip/psMinimize.c	/^#define RETURN_FINAL_BRACKET(/;"	d	file:
+ROT_ANGLE	test/astronomy/tst_psAstrometry01.c	/^#define ROT_ANGLE /;"	d	file:
+ROW0	test/astronomy/tst_psAstrometry01.c	/^#define ROW0 /;"	d	file:
+S16	include/psImage.h	/^        psS16** S16;                   \/\/\/< Signed 16-bit integer data.$/;"	m	union:psImage::<anonymous>
+S16	include/psScalar.h	/^        psS16 S16;              \/\/\/< Signed 16-bit integer data.$/;"	m
+S16	include/psVector.h	/^        psS16* S16;             \/\/\/< Signed 16-bit integer data.$/;"	m
+S16	src/collections/psScalar.h	/^        psS16 S16;              \/\/\/< Signed 16-bit integer data.$/;"	m
+S16	src/collections/psVector.h	/^        psS16* S16;             \/\/\/< Signed 16-bit integer data.$/;"	m
+S16	src/image/psImage.h	/^        psS16** S16;                   \/\/\/< Signed 16-bit integer data.$/;"	m	union:psImage::<anonymous>
+S2R	src/astronomy/psTime.c	/^#define S2R /;"	d	file:
+S32	include/psImage.h	/^        psS32** S32;                   \/\/\/< Signed 32-bit integer data.$/;"	m	union:psImage::<anonymous>
+S32	include/psMetadata.h	/^        psS32 S32;                     \/\/\/< Signed 32-bit integer data.$/;"	m	union:psMetadataItem::<anonymous>
+S32	include/psScalar.h	/^        psS32 S32;              \/\/\/< Signed 32-bit integer data.$/;"	m
+S32	include/psVector.h	/^        psS32* S32;             \/\/\/< Signed 32-bit integer data.$/;"	m
+S32	src/astronomy/psMetadata.h	/^        psS32 S32;                     \/\/\/< Signed 32-bit integer data.$/;"	m	union:psMetadataItem::<anonymous>
+S32	src/collections/psScalar.h	/^        psS32 S32;              \/\/\/< Signed 32-bit integer data.$/;"	m
+S32	src/collections/psVector.h	/^        psS32* S32;             \/\/\/< Signed 32-bit integer data.$/;"	m
+S32	src/image/psImage.h	/^        psS32** S32;                   \/\/\/< Signed 32-bit integer data.$/;"	m	union:psImage::<anonymous>
+S64	include/psImage.h	/^        psS64** S64;                   \/\/\/< Signed 64-bit integer data.$/;"	m	union:psImage::<anonymous>
+S64	include/psScalar.h	/^        psS64 S64;              \/\/\/< Signed 64-bit integer data.$/;"	m
+S64	include/psVector.h	/^        psS64* S64;             \/\/\/< Signed 64-bit integer data.$/;"	m
+S64	src/collections/psScalar.h	/^        psS64 S64;              \/\/\/< Signed 64-bit integer data.$/;"	m
+S64	src/collections/psVector.h	/^        psS64* S64;             \/\/\/< Signed 64-bit integer data.$/;"	m
+S64	src/image/psImage.h	/^        psS64** S64;                   \/\/\/< Signed 64-bit integer data.$/;"	m	union:psImage::<anonymous>
+S8	include/psImage.h	/^        psS8**  S8;                    \/\/\/< Signed 8-bit integer data.$/;"	m	union:psImage::<anonymous>
+S8	include/psScalar.h	/^        psS8 S8;                \/\/\/< Signed 8-bit integer data.$/;"	m
+S8	include/psVector.h	/^        psS8* S8;               \/\/\/< Signed 8-bit integer data.$/;"	m
+S8	src/collections/psScalar.h	/^        psS8 S8;                \/\/\/< Signed 8-bit integer data.$/;"	m
+S8	src/collections/psVector.h	/^        psS8* S8;               \/\/\/< Signed 8-bit integer data.$/;"	m
+S8	src/image/psImage.h	/^        psS8**  S8;                    \/\/\/< Signed 8-bit integer data.$/;"	m	union:psImage::<anonymous>
+SCALAR	src/dataManip/psMatrixVectorArithmetic.c	/^#define SCALAR(/;"	d	file:
+SCALAR_IMAGE	src/dataManip/psMatrixVectorArithmetic.c	/^#define SCALAR_IMAGE(/;"	d	file:
+SCALAR_SCALAR	src/dataManip/psMatrixVectorArithmetic.c	/^#define SCALAR_SCALAR(/;"	d	file:
+SCALAR_VECTOR	src/dataManip/psMatrixVectorArithmetic.c	/^#define SCALAR_VECTOR(/;"	d	file:
+SEC_PER_DAY	src/astronomy/psTime.c	/^                #define  SEC_PER_DAY /;"	d	file:
+SEC_PER_HOUR	src/astronomy/psTime.c	/^                #define  SEC_PER_HOUR /;"	d	file:
+SEC_PER_MINUTE	src/astronomy/psTime.c	/^                #define  SEC_PER_MINUTE /;"	d	file:
+SEC_PER_YEAR	src/astronomy/psTime.c	/^                #define  SEC_PER_YEAR /;"	d	file:
+SEC_TO_RAD	src/astronomy/psCoord.c	/^#define SEC_TO_RAD(/;"	d	file:
+SEED	test/dataManip/tst_psRandom.c	/^#define SEED /;"	d	file:
+SEED2	test/dataManip/tst_psRandom.c	/^#define SEED2 /;"	d	file:
+SLALIB_H	include/slalib.h	/^#define SLALIB_H$/;"	d
+SLALIB_H	src/astronomy/slalib.h	/^#define SLALIB_H$/;"	d
+SORT_INDICES	src/collections/psVector.c	/^    #define SORT_INDICES(/;"	d	file:
+SPACE_INC	test/astronomy/tst_psCoord.c	/^#define SPACE_INC /;"	d	file:
+SPATIAL_CONVOLVE_CASE	src/image/psImageConvolve.c	/^        #define SPATIAL_CONVOLVE_CASE(/;"	d	file:
+SPLINE_ORDER	test/dataManip/tst_psFunc05.c	/^#define SPLINE_ORDER /;"	d	file:
+STDEV	test/dataManip/tst_psMinimize07.c	/^#define STDEV /;"	d	file:
+STDEV	test/dataManip/tst_psStats07.c	/^#define STDEV /;"	d	file:
+TEMPERATURE	test/astronomy/tst_psAstrometry01.c	/^#define TEMPERATURE /;"	d	file:
+THRESHOLD	test/image/tst_psImageStats02.c	/^#define THRESHOLD /;"	d	file:
+TIME_CONFIG_FILE	src/astronomy/psTime.c	/^#define TIME_CONFIG_FILE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix01.c	/^#define TOLERANCE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix03.c	/^#define TOLERANCE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix04.c	/^#define TOLERANCE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix05.c	/^#define TOLERANCE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix06.c	/^#define TOLERANCE /;"	d	file:
+TOLERANCE	test/dataManip/tst_psMatrix07.c	/^#define TOLERANCE /;"	d	file:
+TPCheckBufferPositive	test/sysUtils/tst_psMemory.c	/^psS32 TPCheckBufferPositive( void )$/;"	f
+TPCheckBufferPositive	test/sysUtils/tst_psMemory.c	/^static psS32 TPCheckBufferPositive( void );$/;"	p	file:
+TPFreeReferencedMemory	test/sysUtils/tst_psMemory.c	/^psS32 TPFreeReferencedMemory( void )$/;"	f
+TPFreeReferencedMemory	test/sysUtils/tst_psMemory.c	/^static psS32 TPFreeReferencedMemory( void );$/;"	p	file:
+TPOutOfMemory	test/sysUtils/tst_psMemory.c	/^psS32 TPOutOfMemory( void )$/;"	f
+TPOutOfMemory	test/sysUtils/tst_psMemory.c	/^static psS32 TPOutOfMemory( void );$/;"	p	file:
+TPOutOfMemoryExhaustedCallback	test/sysUtils/tst_psMemory.c	/^psPtr TPOutOfMemoryExhaustedCallback( size_t size )$/;"	f
+TPOutOfMemoryExhaustedCallback	test/sysUtils/tst_psMemory.c	/^static psPtr TPOutOfMemoryExhaustedCallback( size_t size );$/;"	p	file:
+TPReallocOutOfMemory	test/sysUtils/tst_psMemory.c	/^psS32 TPReallocOutOfMemory( void )$/;"	f
+TPReallocOutOfMemory	test/sysUtils/tst_psMemory.c	/^static psS32 TPReallocOutOfMemory( void );$/;"	p	file:
+TPallocCallback	test/sysUtils/tst_psMemory.c	/^psS32 TPallocCallback( void )$/;"	f
+TPallocCallback	test/sysUtils/tst_psMemory.c	/^static psS32 TPallocCallback( void );$/;"	p	file:
+TPcheckLeaks	test/sysUtils/tst_psMemory.c	/^psS32 TPcheckLeaks( void )$/;"	f
+TPcheckLeaks	test/sysUtils/tst_psMemory.c	/^static psS32 TPcheckLeaks( void );$/;"	p	file:
+TPmemCorruption	test/sysUtils/tst_psMemory.c	/^psS32 TPmemCorruption( void )$/;"	f
+TPmemCorruption	test/sysUtils/tst_psMemory.c	/^static psS32 TPmemCorruption( void );$/;"	p	file:
+TPmultipleFree	test/sysUtils/tst_psMemory.c	/^psS32 TPmultipleFree( void )$/;"	f
+TPmultipleFree	test/sysUtils/tst_psMemory.c	/^static psS32 TPmultipleFree( void );$/;"	p	file:
+TPrealloc	test/sysUtils/tst_psMemory.c	/^psS32 TPrealloc( void )$/;"	f
+TPrealloc	test/sysUtils/tst_psMemory.c	/^static psS32 TPrealloc( void );$/;"	p	file:
+TWOPI	src/astronomy/psTime.c	/^#define TWOPI /;"	d	file:
+U16	include/psImage.h	/^        psU16** U16;                   \/\/\/< Unsigned 16-bit integer data.$/;"	m	union:psImage::<anonymous>
+U16	include/psScalar.h	/^        psU16 U16;              \/\/\/< Unsigned 16-bit integer data.$/;"	m
+U16	include/psVector.h	/^        psU16* U16;             \/\/\/< Unsigned 16-bit integer data.$/;"	m
+U16	src/collections/psScalar.h	/^        psU16 U16;              \/\/\/< Unsigned 16-bit integer data.$/;"	m
+U16	src/collections/psVector.h	/^        psU16* U16;             \/\/\/< Unsigned 16-bit integer data.$/;"	m
+U16	src/image/psImage.h	/^        psU16** U16;                   \/\/\/< Unsigned 16-bit integer data.$/;"	m	union:psImage::<anonymous>
+U32	include/psImage.h	/^        psU32** U32;                   \/\/\/< Unsigned 32-bit integer data.$/;"	m	union:psImage::<anonymous>
+U32	include/psScalar.h	/^        psU32 U32;              \/\/\/< Unsigned 32-bit integer data.$/;"	m
+U32	include/psVector.h	/^        psU32* U32;             \/\/\/< Unsigned 32-bit integer data.$/;"	m
+U32	src/collections/psScalar.h	/^        psU32 U32;              \/\/\/< Unsigned 32-bit integer data.$/;"	m
+U32	src/collections/psVector.h	/^        psU32* U32;             \/\/\/< Unsigned 32-bit integer data.$/;"	m
+U32	src/image/psImage.h	/^        psU32** U32;                   \/\/\/< Unsigned 32-bit integer data.$/;"	m	union:psImage::<anonymous>
+U64	include/psImage.h	/^        psU64** U64;                   \/\/\/< Unsigned 64-bit integer data.$/;"	m	union:psImage::<anonymous>
+U64	include/psScalar.h	/^        psU64 U64;              \/\/\/< Unsigned 64-bit integer data.$/;"	m
+U64	include/psVector.h	/^        psU64* U64;             \/\/\/< Unsigned 64-bit integer data.$/;"	m
+U64	src/collections/psScalar.h	/^        psU64 U64;              \/\/\/< Unsigned 64-bit integer data.$/;"	m
+U64	src/collections/psVector.h	/^        psU64* U64;             \/\/\/< Unsigned 64-bit integer data.$/;"	m
+U64	src/image/psImage.h	/^        psU64** U64;                   \/\/\/< Unsigned 64-bit integer data.$/;"	m	union:psImage::<anonymous>
+U8	include/psImage.h	/^        psU8**  U8;                    \/\/\/< Unsigned 8-bit integer data.$/;"	m	union:psImage::<anonymous>
+U8	include/psScalar.h	/^        psU8 U8;                \/\/\/< Unsigned 8-bit integer data.$/;"	m
+U8	include/psVector.h	/^        psU8* U8;               \/\/\/< Unsigned 8-bit integer data.$/;"	m
+U8	src/collections/psScalar.h	/^        psU8 U8;                \/\/\/< Unsigned 8-bit integer data.$/;"	m
+U8	src/collections/psVector.h	/^        psU8* U8;               \/\/\/< Unsigned 8-bit integer data.$/;"	m
+U8	src/image/psImage.h	/^        psU8**  U8;                    \/\/\/< Unsigned 8-bit integer data.$/;"	m	union:psImage::<anonymous>
+UNARY_OP	src/dataManip/psMatrixVectorArithmetic.c	/^#define UNARY_OP(/;"	d	file:
+UNARY_TYPE	src/dataManip/psMatrixVectorArithmetic.c	/^#define UNARY_TYPE(/;"	d	file:
+UNIFORM_MEAN	test/dataManip/tst_psRandom.c	/^#define UNIFORM_MEAN /;"	d	file:
+UNIFORM_STDEV	test/dataManip/tst_psRandom.c	/^#define UNIFORM_STDEV /;"	d	file:
+UNKNOWN_OP	src/collections/psBitSet.c	/^    UNKNOWN_OP,$/;"	e	file:
+UPPER	test/dataManip/tst_psHist00.c	/^#define UPPER /;"	d	file:
+UPPER	test/dataManip/tst_psHist01.c	/^#define UPPER /;"	d	file:
+UPPER	test/dataManip/tst_psHist02.c	/^#define UPPER /;"	d	file:
+UPPER	test/dataManip/tst_psHist03.c	/^#define UPPER /;"	d	file:
+USEC_PER_DAY	src/astronomy/psTime.c	/^                #define USEC_PER_DAY /;"	d	file:
+UpdateHistogramBins	src/dataManip/psStats.c	/^psS32 UpdateHistogramBins(psS32 binNum,$/;"	f
+V	include/psImage.h	/^        psPtr*  V;                     \/\/\/< Pointer to data.$/;"	m	union:psImage::<anonymous>
+V	include/psMetadata.h	/^        psPtr V;                       \/\/\/< Pointer to other type of data.$/;"	m	union:psMetadataItem::<anonymous>
+V	include/psVector.h	/^        psPtr V;                \/\/\/< Pointer to data.$/;"	m
+V	src/astronomy/psMetadata.h	/^        psPtr V;                       \/\/\/< Pointer to other type of data.$/;"	m	union:psMetadataItem::<anonymous>
+V	src/collections/psVector.h	/^        psPtr V;                \/\/\/< Pointer to data.$/;"	m
+V	src/image/psImage.h	/^        psPtr*  V;                     \/\/\/< Pointer to data.$/;"	m	union:psImage::<anonymous>
+VECTOR	src/dataManip/psMatrixVectorArithmetic.c	/^#define VECTOR(/;"	d	file:
+VECTOR_IMAGE	src/dataManip/psMatrixVectorArithmetic.c	/^#define VECTOR_IMAGE(/;"	d	file:
+VECTOR_SCALAR	src/dataManip/psMatrixVectorArithmetic.c	/^#define VECTOR_SCALAR(/;"	d	file:
+VECTOR_VECTOR	src/dataManip/psMatrixVectorArithmetic.c	/^#define VECTOR_VECTOR(/;"	d	file:
+VectorFitPolynomial1DCheby	src/dataManip/psMinimize.c	/^psPolynomial1D *VectorFitPolynomial1DCheby(psPolynomial1D* myPoly,$/;"	f
+VectorFitPolynomial1DOrd	src/dataManip/psMinimize.c	/^psPolynomial1D* VectorFitPolynomial1DOrd(psPolynomial1D* myPoly,$/;"	f
+WAVELENGTH	test/astronomy/tst_psAstrometry01.c	/^#define WAVELENGTH /;"	d	file:
+X0	test/astronomy/tst_psAstrometry01.c	/^#define X0 /;"	d	file:
+X0_BIG	test/astronomy/tst_psCoord.c	/^#define X0_BIG /;"	d	file:
+X0_SMALL	test/astronomy/tst_psCoord.c	/^#define X0_SMALL /;"	d	file:
+XOR_OP	src/collections/psBitSet.c	/^    XOR_OP,$/;"	e	file:
+X_NUM_COLS	test/astronomy/tst_psAstrometry01.c	/^#define X_NUM_COLS /;"	d	file:
+X_NUM_ROWS	test/astronomy/tst_psAstrometry01.c	/^#define X_NUM_ROWS /;"	d	file:
+X_SCALE	test/astronomy/tst_psAstrometry01.c	/^#define X_SCALE /;"	d	file:
+Xs	include/psCoord.h	/^    double Xs;                  \/\/\/< plate-scale in X direction$/;"	m
+Xs	src/astronomy/psCoord.h	/^    double Xs;                  \/\/\/< plate-scale in X direction$/;"	m
+Y0	test/astronomy/tst_psAstrometry01.c	/^#define Y0 /;"	d	file:
+YERR	test/dataManip/tst_psMinimize04.c	/^#define YERR /;"	d	file:
+YERR	test/dataManip/tst_psMinimize04_F32.c	/^#define YERR /;"	d	file:
+Y_NUM_COLS	test/astronomy/tst_psAstrometry01.c	/^#define Y_NUM_COLS /;"	d	file:
+Y_NUM_ROWS	test/astronomy/tst_psAstrometry01.c	/^#define Y_NUM_ROWS /;"	d	file:
+Y_SCALE	test/astronomy/tst_psAstrometry01.c	/^#define Y_SCALE /;"	d	file:
+Ys	include/psCoord.h	/^    double Ys;                  \/\/\/< plate-scale in Y direction$/;"	m
+Ys	src/astronomy/psCoord.h	/^    double Ys;                  \/\/\/< plate-scale in Y direction$/;"	m
+ZD	test/astronomy/tst_psAstrometry01.c	/^#define ZD /;"	d	file:
+__STRICT_ANSI__	src/fileUtils/psLookupTable.c	/^#define __STRICT_ANSI__$/;"	d	file:
+__STRICT_ANSI__	src/fileUtils/psLookupTable.c	/^#undef __STRICT_ANSI__$/;"	d	file:
+_details	docs/html/group__MemoryManagement.html	/^<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/group__memCallback.html	/^<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/group__memRefCount.html	/^<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/group__memTracing.html	/^<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psAbort_8h.html	/^<h1>psAbort.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psArray_8h.html	/^<h1>psArray.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psAstrometry_8h.html	/^<h1>psAstrometry.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psAstronomyErrors_8h.html	/^<h1>psAstronomyErrors.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psBitSet_8h.html	/^<h1>psBitSet.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psCollectionsErrors_8h.html	/^<h1>psCollectionsErrors.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psCompare_8h.html	/^<h1>psCompare.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psConfigure_8h.html	/^<h1>psConfigure.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psCoord_8h.html	/^<h1>psCoord.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psDataManipErrors_8h.html	/^<h1>psDataManipErrors.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psErrorCodes_8h.html	/^<h1>psErrorCodes.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psError_8h.html	/^<h1>psError.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psFunctions_8h.html	/^<h1>psFunctions.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psHash_8h.html	/^<h1>psHash.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageConvolve_8h.html	/^<h1>psImageConvolve.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageErrors_8h.html	/^<h1>psImageErrors.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageExtraction_8h.html	/^<h1>psImageExtraction.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageFFT_8h.html	/^<h1>psImageFFT.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageIO_8h.html	/^<h1>psImageIO.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageManip_8h.html	/^<h1>psImageManip.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImageStats_8h.html	/^<h1>psImageStats.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psImage_8h.html	/^<h1>psImage.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psList_8h.html	/^<h1>psList.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psLogMsg_8h.html	/^<h1>psLogMsg.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMatrixVectorArithmetic_8h.html	/^<h1>psMatrixVectorArithmetic.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMatrix_8h.html	/^<h1>psMatrix.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMemory_8h.html	/^<h1>psMemory.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMetadataIO_8h.html	/^<h1>psMetadataIO.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMetadata_8h.html	/^<h1>psMetadata.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psMinimize_8h.html	/^<h1>psMinimize.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psPhotometry_8h.html	/^<h1>psPhotometry.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psRandom_8h.html	/^<h1>psRandom.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psScalar_8h.html	/^<h1>psScalar.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psStats_8h.html	/^<h1>psStats.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psString_8h.html	/^<h1>psString.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psSysUtilsErrors_8h.html	/^<h1>psSysUtilsErrors.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psTime_8h.html	/^<h1>psTime.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psTrace_8h.html	/^<h1>psTrace.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psType_8h.html	/^<h1>psType.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psVectorFFT_8h.html	/^<h1>psVectorFFT.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/psVector_8h.html	/^<h1>psVector.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/pslib_8h.html	/^<h1>pslib.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/slalib_8h.html	/^<h1>slalib.h File Reference<\/h1><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structp__psComponent.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsArray.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsBitSet.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsCell.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsChip.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsDPolynomial1D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsDPolynomial2D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsDPolynomial3D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsDPolynomial4D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsErr.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsErrorDescription.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsExposure.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsFPA.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsFixedPattern.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsGrommit.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsHash.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsHashBucket.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsHistogram.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsImage.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsKernel.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsList.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsListElem.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsListIterator.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsMemBlock.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsMetadata.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsMetadataItem.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsObservatory.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPhotSystem.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPhotTransform.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPlane.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPlaneDistort.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPlaneTransform.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPolynomial1D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPolynomial2D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPolynomial3D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsPolynomial4D.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsProjection.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsReadout.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsRegion.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsScalar.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsSphere.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsSphereTransform.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsStats.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsTime.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsType.html	/^<hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+_details	docs/html/structpsVector.html	/^<center><font size="2">[<a href="graph_legend.html">legend<\/a>]<\/font><\/center><hr><a name="_details"><\/a><h2>Detailed Description<\/h2>$/;"	a
+a0	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a0" doxytag="psAstronomyErrors.h::PS_ERRORNAME_DOMAIN" ><\/a><p>$/;"	a
+a0	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a0" doxytag="psCollectionsErrors.h::PS_ERRORNAME_DOMAIN" ><\/a><p>$/;"	a
+a0	docs/html/psCompare_8h.html	/^<a class="anchor" name="a0" doxytag="psCompare.h::PS_COMPARE_H" ><\/a><p>$/;"	a
+a0	docs/html/psConstants_8h.html	/^<a class="anchor" name="a0" doxytag="psConstants.h::PS_DETERMINE_BRACKET_STEP_SIZE" ><\/a><p>$/;"	a
+a0	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a0" doxytag="psDataManipErrors.h::PS_ERRORNAME_DOMAIN" ><\/a><p>$/;"	a
+a0	docs/html/psFunctions_8h.html	/^<a class="anchor" name="a0" doxytag="psFunctions.h::PS_FUNCTIONS_H" ><\/a><p>$/;"	a
+a0	docs/html/psHash_8h.html	/^<a class="anchor" name="a0" doxytag="psHash.h::PS_HASH_H" ><\/a><p>$/;"	a
+a0	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a0" doxytag="psImageConvolve.h::PS_TYPE_KERNEL" ><\/a><p>$/;"	a
+a0	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a0" doxytag="psImageErrors.h::PS_ERRORNAME_DOMAIN" ><\/a><p>$/;"	a
+a0	docs/html/psImageStats_8h.html	/^<a class="anchor" name="a0" doxytag="psImageStats.h::PS_IMAGE_STATS_H" ><\/a><p>$/;"	a
+a0	docs/html/psList_8h.html	/^<a class="anchor" name="a0" doxytag="psList.h::PS_LIST_H" ><\/a><p>$/;"	a
+a0	docs/html/psLogMsg_8h.html	/^<a class="anchor" name="a0" doxytag="psLogMsg.h::PS_LOG_MSG_H" ><\/a><p>$/;"	a
+a0	docs/html/psMemory_8h.html	/^<a class="anchor" name="a0" doxytag="psMemory.h::PS_MEMORY_H" ><\/a><p>$/;"	a
+a0	docs/html/psMinimize_8h.html	/^<a class="anchor" name="a0" doxytag="psMinimize.h::PS_MINIMIZE_H" ><\/a><p>$/;"	a
+a0	docs/html/psRandom_8h.html	/^<a class="anchor" name="a0" doxytag="psRandom.h::PS_FUNCTIONS_H" ><\/a><p>$/;"	a
+a0	docs/html/psStats_8h.html	/^<a class="anchor" name="a0" doxytag="psStats.h::PS_STATS_H" ><\/a><p>$/;"	a
+a0	docs/html/psString_8h.html	/^<a class="anchor" name="a0" doxytag="psString.h::PS_STRING" ><\/a><p>$/;"	a
+a0	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a0" doxytag="psSysUtilsErrors.h::PS_ERRORNAME_DOMAIN" ><\/a><p>$/;"	a
+a0	docs/html/psTrace_8h.html	/^<a class="anchor" name="a0" doxytag="psTrace.h::PS_TRACE_H" ><\/a><p>$/;"	a
+a0	docs/html/slalib_8h.html	/^<a class="anchor" name="a0" doxytag="slalib.h::fslaAoppa" ><\/a><p>$/;"	a
+a1	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a1" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_FILE_NOT_FOUND" ><\/a><p>$/;"	a
+a1	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a1" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psArray_REALLOC_NULL" ><\/a><p>$/;"	a
+a1	docs/html/psConstants_8h.html	/^<a class="anchor" name="a1" doxytag="psConstants.h::PS_MAX_LMM_ITERATIONS" ><\/a><p>$/;"	a
+a1	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a1" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_TYPE_NOT_F32_C32" ><\/a><p>$/;"	a
+a1	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a1" doxytag="psImageConvolve.h::PS_TYPE_KERNEL_DATA" ><\/a><p>$/;"	a
+a1	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a1" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_AREA_NEGATIVE" ><\/a><p>$/;"	a
+a1	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a1" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED" ><\/a><p>$/;"	a
+a1	docs/html/psTrace_8h.html	/^<a class="anchor" name="a1" doxytag="psTrace.h::PS_UNKNOWN_TRACE_LEVEL" ><\/a><p>$/;"	a
+a1	docs/html/slalib_8h.html	/^<a class="anchor" name="a1" doxytag="slalib.h::fslaAopqk" ><\/a><p>$/;"	a
+a10	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a10" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a10	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a10" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_OPERATOR_INVALID" ><\/a><p>$/;"	a
+a10	docs/html/psConstants_8h.html	/^<a class="anchor" name="a10" doxytag="psConstants.h::PS_INT_CHECK_RANGE" ><\/a><p>$/;"	a
+a10	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a10" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET" ><\/a><p>$/;"	a
+a10	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a10" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_NOT_PARENT" ><\/a><p>$/;"	a
+a10	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a10" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psMemory_MULTIPLE_FREE" ><\/a><p>$/;"	a
+a10	docs/html/slalib_8h.html	/^<a class="anchor" name="a10" doxytag="slalib.h::fslaOapqk" ><\/a><p>$/;"	a
+a11	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a11" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_GET_TOD_FAILED" ><\/a><p>$/;"	a
+a11	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a11" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL" ><\/a><p>$/;"	a
+a11	docs/html/psConstants_8h.html	/^<a class="anchor" name="a11" doxytag="psConstants.h::PS_INT_COMPARE" ><\/a><p>$/;"	a
+a11	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a11" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_NOT_F32_F64" ><\/a><p>$/;"	a
+a11	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a11" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED" ><\/a><p>$/;"	a
+a11	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a11" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psString_NCHAR_NEGATIVE" ><\/a><p>$/;"	a
+a11	docs/html/slalib_8h.html	/^<a class="anchor" name="a11" doxytag="slalib.h::fslaAirmas" ><\/a><p>$/;"	a
+a12	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a12" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED" ><\/a><p>$/;"	a
+a12	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a12" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL" ><\/a><p>$/;"	a
+a12	docs/html/psConstants_8h.html	/^<a class="anchor" name="a12" doxytag="psConstants.h::PS_FLOAT_COMPARE" ><\/a><p>$/;"	a
+a12	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a12" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a12	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a12" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SUBSET_ZERO_SIZE" ><\/a><p>$/;"	a
+a12	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a12" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT" ><\/a><p>$/;"	a
+a13	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a13" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED" ><\/a><p>$/;"	a
+a13	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a13" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER" ><\/a><p>$/;"	a
+a13	docs/html/psConstants_8h.html	/^<a class="anchor" name="a13" doxytag="psConstants.h::PS_FLOAT_CHECK_NON_EQUAL" ><\/a><p>$/;"	a
+a13	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a13" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE" ><\/a><p>$/;"	a
+a13	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a13" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE" ><\/a><p>$/;"	a
+a13	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a13" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psTrace_NULL_TRACETREE" ><\/a><p>$/;"	a
+a14	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a14" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_USEC_INVALID" ><\/a><p>$/;"	a
+a14	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a14" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_NOT_OP_FAILED" ><\/a><p>$/;"	a
+a14	docs/html/psConstants_8h.html	/^<a class="anchor" name="a14" doxytag="psConstants.h::PS_PTR_CHECK_NULL" ><\/a><p>$/;"	a
+a14	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a14" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED" ><\/a><p>$/;"	a
+a14	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a14" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE" ><\/a><p>$/;"	a
+a14	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a14" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT" ><\/a><p>$/;"	a
+a15	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a15" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_ISOTIME_MALFORMED" ><\/a><p>$/;"	a
+a15	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a15" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_OPERAND_NULL" ><\/a><p>$/;"	a
+a15	docs/html/psConstants_8h.html	/^<a class="anchor" name="a15" doxytag="psConstants.h::PS_PTR_CHECK_NULL_GENERAL" ><\/a><p>$/;"	a
+a15	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a15" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_FAILED" ><\/a><p>$/;"	a
+a15	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a15" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_BAD_STAT" ><\/a><p>$/;"	a
+a15	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a15" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME" ><\/a><p>$/;"	a
+a16	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a16" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_INTERPOLATION_FAILED" ><\/a><p>$/;"	a
+a16	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a16" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE" ><\/a><p>$/;"	a
+a16	docs/html/psConstants_8h.html	/^<a class="anchor" name="a16" doxytag="psConstants.h::PS_PTR_CHECK_TYPE" ><\/a><p>$/;"	a
+a16	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a16" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM" ><\/a><p>$/;"	a
+a16	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a16" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_NO_STAT_OPTIONS" ><\/a><p>$/;"	a
+a16	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a16" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT" ><\/a><p>$/;"	a
+a17	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a17" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME" ><\/a><p>$/;"	a
+a17	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a17" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psScalar_COPY_NULL" ><\/a><p>$/;"	a
+a17	docs/html/psConstants_8h.html	/^<a class="anchor" name="a17" doxytag="psConstants.h::PS_PTR_CHECK_DIMEN" ><\/a><p>$/;"	a
+a17	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a17" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM" ><\/a><p>$/;"	a
+a17	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a17" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_STAT_NULL" ><\/a><p>$/;"	a
+a17	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a17" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION" ><\/a><p>$/;"	a
+a18	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a18" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED" ><\/a><p>$/;"	a
+a18	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a18" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psHash_KEY_NULL" ><\/a><p>$/;"	a
+a18	docs/html/psConstants_8h.html	/^<a class="anchor" name="a18" doxytag="psConstants.h::PS_PTR_CHECK_DIMEN_GENERAL" ><\/a><p>$/;"	a
+a18	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a18" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT" ><\/a><p>$/;"	a
+a18	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a18" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID" ><\/a><p>$/;"	a
+a18	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a18" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED" ><\/a><p>$/;"	a
+a19	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a19" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_BAD_TABLE_COUNT" ><\/a><p>$/;"	a
+a19	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a19" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psHash_TABLE_NULL" ><\/a><p>$/;"	a
+a19	docs/html/psConstants_8h.html	/^<a class="anchor" name="a19" doxytag="psConstants.h::PS_PTR_CHECK_SIZE_EQUAL" ><\/a><p>$/;"	a
+a19	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a19" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN" ><\/a><p>$/;"	a
+a19	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a19" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE" ><\/a><p>$/;"	a
+a19	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a19" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED" ><\/a><p>$/;"	a
+a2	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a2" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_FILE_TOO_MANY_ROWS" ><\/a><p>$/;"	a
+a2	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a2" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psVector_REALLOC_NULL" ><\/a><p>$/;"	a
+a2	docs/html/psConstants_8h.html	/^<a class="anchor" name="a2" doxytag="psConstants.h::PS_MAX_MINIMIZE_ITERATIONS" ><\/a><p>$/;"	a
+a2	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a2" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_REVERSE_NOT_COMPLEX" ><\/a><p>$/;"	a
+a2	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a2" doxytag="psImageConvolve.h::PS_TYPE_KERNEL_NAME" ><\/a><p>$/;"	a
+a2	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a2" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_NOT_AN_IMAGE" ><\/a><p>$/;"	a
+a2	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a2" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID" ><\/a><p>$/;"	a
+a2	docs/html/psTrace_8h.html	/^<a class="anchor" name="a2" doxytag="psTrace.h::PS_DEFAULT_TRACE_LEVEL" ><\/a><p>$/;"	a
+a2	docs/html/slalib_8h.html	/^<a class="anchor" name="a2" doxytag="slalib.h::fslaOapqk" ><\/a><p>$/;"	a
+a20	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a20" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_BAD_VECTOR" ><\/a><p>$/;"	a
+a20	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a20" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psHash_DATA_NULL" ><\/a><p>$/;"	a
+a20	docs/html/psConstants_8h.html	/^<a class="anchor" name="a20" doxytag="psConstants.h::PS_PTR_CHECK_TYPE_EQUAL" ><\/a><p>$/;"	a
+a20	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a20" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS" ><\/a><p>$/;"	a
+a20	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a20" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_nSamples_TOOSMALL" ><\/a><p>$/;"	a
+a20	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a20" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED" ><\/a><p>$/;"	a
+a21	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a21" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED" ><\/a><p>$/;"	a
+a21	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a21" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_LOCATION_INVALID" ><\/a><p>$/;"	a
+a21	docs/html/psConstants_8h.html	/^<a class="anchor" name="a21" doxytag="psConstants.h::PS_PTR_CHECK_TYPE_EQUAL_GENERAL" ><\/a><p>$/;"	a
+a21	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a21" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE" ><\/a><p>$/;"	a
+a21	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a21" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE" ><\/a><p>$/;"	a
+a22	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a22" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN" ><\/a><p>$/;"	a
+a22	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a22" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_ITERATOR_INVALID" ><\/a><p>$/;"	a
+a22	docs/html/psConstants_8h.html	/^<a class="anchor" name="a22" doxytag="psConstants.h::PS_VECTOR_CHECK_NULL" ><\/a><p>$/;"	a
+a22	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a22" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE" ><\/a><p>$/;"	a
+a22	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a22" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_RADII_VECTOR_NULL" ><\/a><p>$/;"	a
+a23	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a23" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psCoord_UNITS_UNKNOWN" ><\/a><p>$/;"	a
+a23	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a23" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_ITERATOR_NULL" ><\/a><p>$/;"	a
+a23	docs/html/psConstants_8h.html	/^<a class="anchor" name="a23" doxytag="psConstants.h::PS_VECTOR_CHECK_NULL_GENERAL" ><\/a><p>$/;"	a
+a23	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a23" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED" ><\/a><p>$/;"	a
+a23	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a23" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE" ><\/a><p>$/;"	a
+a24	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a24" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN" ><\/a><p>$/;"	a
+a24	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a24" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_LIST_NULL" ><\/a><p>$/;"	a
+a24	docs/html/psConstants_8h.html	/^<a class="anchor" name="a24" doxytag="psConstants.h::PS_VECTOR_CHECK_EMPTY" ><\/a><p>$/;"	a
+a24	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a24" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS" ><\/a><p>$/;"	a
+a24	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a24" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL" ><\/a><p>$/;"	a
+a25	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a25" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM" ><\/a><p>$/;"	a
+a25	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a25" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_DATA_NULL" ><\/a><p>$/;"	a
+a25	docs/html/psConstants_8h.html	/^<a class="anchor" name="a25" doxytag="psConstants.h::PS_VECTOR_CHECK_TYPE_F32_OR_F64" ><\/a><p>$/;"	a
+a25	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a25" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE" ><\/a><p>$/;"	a
+a25	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a25" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_IMAGE_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a26	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a26" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_METATYPE_INVALID" ><\/a><p>$/;"	a
+a26	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a26" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psList_DATA_NOT_FOUND" ><\/a><p>$/;"	a
+a26	docs/html/psConstants_8h.html	/^<a class="anchor" name="a26" doxytag="psConstants.h::PS_VECTOR_CHECK_TYPE" ><\/a><p>$/;"	a
+a26	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a26" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_COUNT_DIFFERS" ><\/a><p>$/;"	a
+a26	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a26" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_REVERSE_NOT_COMPLEX" ><\/a><p>$/;"	a
+a27	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a27" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH" ><\/a><p>$/;"	a
+a27	docs/html/psConstants_8h.html	/^<a class="anchor" name="a27" doxytag="psConstants.h::PS_VECTOR_CHECK_SIZE_EQUAL" ><\/a><p>$/;"	a
+a27	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a27" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS" ><\/a><p>$/;"	a
+a27	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a27" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_FORWARD_NOT_REAL" ><\/a><p>$/;"	a
+a28	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a28" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED" ><\/a><p>$/;"	a
+a28	docs/html/psConstants_8h.html	/^<a class="anchor" name="a28" doxytag="psConstants.h::PS_VECTOR_F64_TO_F32" ><\/a><p>$/;"	a
+a28	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a28" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a28	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a28" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL" ><\/a><p>$/;"	a
+a29	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a29" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED" ><\/a><p>$/;"	a
+a29	docs/html/psConstants_8h.html	/^<a class="anchor" name="a29" doxytag="psConstants.h::PS_VECTOR_F32_TO_F64" ><\/a><p>$/;"	a
+a29	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a29" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT" ><\/a><p>$/;"	a
+a29	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a29" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a3	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a3" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLE" ><\/a><p>$/;"	a
+a3	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a3" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psVector_NOT_A_VECTOR" ><\/a><p>$/;"	a
+a3	docs/html/psConstants_8h.html	/^<a class="anchor" name="a3" doxytag="psConstants.h::PS_LEFT_SPLINE_DERIV" ><\/a><p>$/;"	a
+a3	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a3" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_FORWARD_NOT_REAL" ><\/a><p>$/;"	a
+a3	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a3" doxytag="psImageConvolve.h::psKernelType" ><\/a><p>$/;"	a
+a3	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a3" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_IMAGE_NULL" ><\/a><p>$/;"	a
+a3	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a3" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED" ><\/a><p>$/;"	a
+a3	docs/html/psTrace_8h.html	/^<a class="anchor" name="a3" doxytag="psTrace.h::PS_THE_OTHER_DEFAULT_TRACE_LEVEL" ><\/a><p>$/;"	a
+a3	docs/html/slalib_8h.html	/^<a class="anchor" name="a3" doxytag="slalib.h::fslaAirmas" ><\/a><p>$/;"	a
+a30	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a30" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED" ><\/a><p>$/;"	a
+a30	docs/html/psConstants_8h.html	/^<a class="anchor" name="a30" doxytag="psConstants.h::PS_VECTOR_PRINT" ><\/a><p>$/;"	a
+a30	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a30" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT" ><\/a><p>$/;"	a
+a30	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a30" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH" ><\/a><p>$/;"	a
+a31	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a31" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED" ><\/a><p>$/;"	a
+a31	docs/html/psConstants_8h.html	/^<a class="anchor" name="a31" doxytag="psConstants.h::PS_VECTOR_CONVERT_F64_TO_F32_STATIC" ><\/a><p>$/;"	a
+a31	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a31" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED" ><\/a><p>$/;"	a
+a31	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a31" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED" ><\/a><p>$/;"	a
+a32	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a32" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED" ><\/a><p>$/;"	a
+a32	docs/html/psConstants_8h.html	/^<a class="anchor" name="a32" doxytag="psConstants.h::PS_VECTOR_CONVERT_F32_TO_F64_STATIC" ><\/a><p>$/;"	a
+a32	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a32" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_DIMEN_OTHER_FOUND" ><\/a><p>$/;"	a
+a32	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a32" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED" ><\/a><p>$/;"	a
+a33	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a33" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED" ><\/a><p>$/;"	a
+a33	docs/html/psConstants_8h.html	/^<a class="anchor" name="a33" doxytag="psConstants.h::PS_VECTOR_GEN_YERR_STATIC_F32" ><\/a><p>$/;"	a
+a33	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a33" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED" ><\/a><p>$/;"	a
+a33	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a33" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED" ><\/a><p>$/;"	a
+a34	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a34" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_ADD_FAILED" ><\/a><p>$/;"	a
+a34	docs/html/psConstants_8h.html	/^<a class="anchor" name="a34" doxytag="psConstants.h::PS_VECTOR_GEN_YERR_STATIC_F64" ><\/a><p>$/;"	a
+a34	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a34" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED" ><\/a><p>$/;"	a
+a34	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a34" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE" ><\/a><p>$/;"	a
+a35	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a35" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_FIND_FAILED" ><\/a><p>$/;"	a
+a35	docs/html/psConstants_8h.html	/^<a class="anchor" name="a35" doxytag="psConstants.h::PS_VECTOR_GEN_X_INDEX_STATIC_F32" ><\/a><p>$/;"	a
+a35	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a35" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_DIMEN_INVALID" ><\/a><p>$/;"	a
+a35	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a35" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION" ><\/a><p>$/;"	a
+a36	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a36" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED" ><\/a><p>$/;"	a
+a36	docs/html/psConstants_8h.html	/^<a class="anchor" name="a36" doxytag="psConstants.h::PS_VECTOR_GEN_X_INDEX_STATIC_F64" ><\/a><p>$/;"	a
+a36	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a36" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_VECTOR_EMPTY" ><\/a><p>$/;"	a
+a36	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a36" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_FILENAME_NULL" ><\/a><p>$/;"	a
+a37	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a37" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_TYPE_INVALID" ><\/a><p>$/;"	a
+a37	docs/html/psConstants_8h.html	/^<a class="anchor" name="a37" doxytag="psConstants.h::PS_VECTOR_GEN_STATIC_RECYCLED" ><\/a><p>$/;"	a
+a37	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a37" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_IMAGE_EMPTY" ><\/a><p>$/;"	a
+a37	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a37" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_FILENAME_INVALID" ><\/a><p>$/;"	a
+a38	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a38" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE" ><\/a><p>$/;"	a
+a38	docs/html/psConstants_8h.html	/^<a class="anchor" name="a38" doxytag="psConstants.h::PS_VECTOR_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a38	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a38" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH" ><\/a><p>$/;"	a
+a38	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a38" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_EXTNAME_INVALID" ><\/a><p>$/;"	a
+a39	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a39" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID" ><\/a><p>$/;"	a
+a39	docs/html/psConstants_8h.html	/^<a class="anchor" name="a39" doxytag="psConstants.h::PS_POLY_CHECK_NULL" ><\/a><p>$/;"	a
+a39	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a39" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_EXTNUM_INVALID" ><\/a><p>$/;"	a
+a4	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a4" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TIME_PREDATES_TABLE" ><\/a><p>$/;"	a
+a4	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a4" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psVector_SORT_NULL" ><\/a><p>$/;"	a
+a4	docs/html/psConstants_8h.html	/^<a class="anchor" name="a4" doxytag="psConstants.h::PS_RIGHT_SPLINE_DERIV" ><\/a><p>$/;"	a
+a4	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a4" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL" ><\/a><p>$/;"	a
+a4	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a4" doxytag="psImageConvolve.h::psKernelAlloc" ><\/a><p>$/;"	a
+a4	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a4" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a4	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a4" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL" ><\/a><p>$/;"	a
+a4	docs/html/psTrace_8h.html	/^<a class="anchor" name="a4" doxytag="psTrace.h::psTrace" ><\/a><p>$/;"	a
+a4	docs/html/slalib_8h.html	/^<a class="anchor" name="a4" doxytag="slalib.h::slaAoppa" ><\/a><p>$/;"	a
+a40	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a40" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_ADD_FAILED" ><\/a><p>$/;"	a
+a40	docs/html/psConstants_8h.html	/^<a class="anchor" name="a40" doxytag="psConstants.h::PS_POLY_CHECK_TYPE" ><\/a><p>$/;"	a
+a40	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a40" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN" ><\/a><p>$/;"	a
+a41	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a41" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED" ><\/a><p>$/;"	a
+a41	docs/html/psConstants_8h.html	/^<a class="anchor" name="a41" doxytag="psConstants.h::PS_POLY_1D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a41	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a41" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN" ><\/a><p>$/;"	a
+a42	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a42" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR" ><\/a><p>$/;"	a
+a42	docs/html/psConstants_8h.html	/^<a class="anchor" name="a42" doxytag="psConstants.h::PS_POLY_2D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a42	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a42" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN" ><\/a><p>$/;"	a
+a43	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a43" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL" ><\/a><p>$/;"	a
+a43	docs/html/psConstants_8h.html	/^<a class="anchor" name="a43" doxytag="psConstants.h::PS_POLY_3D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a43	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a43" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED" ><\/a><p>$/;"	a
+a44	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a44" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID" ><\/a><p>$/;"	a
+a44	docs/html/psConstants_8h.html	/^<a class="anchor" name="a44" doxytag="psConstants.h::PS_POLY_4D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a44	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a44" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a45	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a45" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM" ><\/a><p>$/;"	a
+a45	docs/html/psConstants_8h.html	/^<a class="anchor" name="a45" doxytag="psConstants.h::PS_POLY_1D_D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a45	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a45" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_READ_FAILED" ><\/a><p>$/;"	a
+a46	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a46" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_PARSE_FAILED" ><\/a><p>$/;"	a
+a46	docs/html/psConstants_8h.html	/^<a class="anchor" name="a46" doxytag="psConstants.h::PS_POLY_2D_D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a46	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a46" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a47	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a47" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_NO_NAME" ><\/a><p>$/;"	a
+a47	docs/html/psConstants_8h.html	/^<a class="anchor" name="a47" doxytag="psConstants.h::PS_POLY_3D_D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a47	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a47" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID" ><\/a><p>$/;"	a
+a48	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a48" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE" ><\/a><p>$/;"	a
+a48	docs/html/psConstants_8h.html	/^<a class="anchor" name="a48" doxytag="psConstants.h::PS_POLY_4D_D_DECLARE_ALLOC_STATIC" ><\/a><p>$/;"	a
+a48	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a48" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED" ><\/a><p>$/;"	a
+a49	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a49" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH" ><\/a><p>$/;"	a
+a49	docs/html/psConstants_8h.html	/^<a class="anchor" name="a49" doxytag="psConstants.h::PS_IMAGE_CHECK_NULL" ><\/a><p>$/;"	a
+a49	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a49" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED" ><\/a><p>$/;"	a
+a5	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a5" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES" ><\/a><p>$/;"	a
+a5	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a5" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE" ><\/a><p>$/;"	a
+a5	docs/html/psConstants_8h.html	/^<a class="anchor" name="a5" doxytag="psConstants.h::PS_ONE" ><\/a><p>$/;"	a
+a5	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a5" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED" ><\/a><p>$/;"	a
+a5	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a5" doxytag="psImageConvolve.h::psKernelGenerate" ><\/a><p>$/;"	a
+a5	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a5" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID" ><\/a><p>$/;"	a
+a5	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a5" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY" ><\/a><p>$/;"	a
+a5	docs/html/slalib_8h.html	/^<a class="anchor" name="a5" doxytag="slalib.h::slaAopqk" ><\/a><p>$/;"	a
+a50	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a50" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN" ><\/a><p>$/;"	a
+a50	docs/html/psConstants_8h.html	/^<a class="anchor" name="a50" doxytag="psConstants.h::PS_IMAGE_CHECK_NULL_GENERAL" ><\/a><p>$/;"	a
+a50	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a50" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED" ><\/a><p>$/;"	a
+a51	docs/html/psConstants_8h.html	/^<a class="anchor" name="a51" doxytag="psConstants.h::PS_IMAGE_CHECK_EMPTY" ><\/a><p>$/;"	a
+a51	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a51" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageIO_WRITE_FAILED" ><\/a><p>$/;"	a
+a52	docs/html/psConstants_8h.html	/^<a class="anchor" name="a52" doxytag="psConstants.h::PS_IMAGE_CHECK_EMPTY_GENERAL" ><\/a><p>$/;"	a
+a52	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a52" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_MAXMIN" ><\/a><p>$/;"	a
+a53	docs/html/psConstants_8h.html	/^<a class="anchor" name="a53" doxytag="psConstants.h::PS_IMAGE_CHECK_TYPE" ><\/a><p>$/;"	a
+a53	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a53" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_MAXMIN_REAL" ><\/a><p>$/;"	a
+a54	docs/html/psConstants_8h.html	/^<a class="anchor" name="a54" doxytag="psConstants.h::PS_IMAGE_CHECK_SIZE_EQUAL" ><\/a><p>$/;"	a
+a54	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a54" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_MAXMIN_IMAG" ><\/a><p>$/;"	a
+a55	docs/html/psConstants_8h.html	/^<a class="anchor" name="a55" doxytag="psConstants.h::PS_IMAGE_CHECK_SIZE" ><\/a><p>$/;"	a
+a55	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a55" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_OPERATION_NULL" ><\/a><p>$/;"	a
+a56	docs/html/psConstants_8h.html	/^<a class="anchor" name="a56" doxytag="psConstants.h::PS_READOUT_CHECK_NULL" ><\/a><p>$/;"	a
+a56	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a56" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a57	docs/html/psConstants_8h.html	/^<a class="anchor" name="a57" doxytag="psConstants.h::PS_READOUT_CHECK_EMPTY" ><\/a><p>$/;"	a
+a57	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a57" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID" ><\/a><p>$/;"	a
+a58	docs/html/psConstants_8h.html	/^<a class="anchor" name="a58" doxytag="psConstants.h::PS_READOUT_CHECK_TYPE" ><\/a><p>$/;"	a
+a58	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a58" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID" ><\/a><p>$/;"	a
+a59	docs/html/psConstants_8h.html	/^<a class="anchor" name="a59" doxytag="psConstants.h::PS_MAX" ><\/a><p>$/;"	a
+a59	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a59" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE" ><\/a><p>$/;"	a
+a6	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a6" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES" ><\/a><p>$/;"	a
+a6	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a6" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE" ><\/a><p>$/;"	a
+a6	docs/html/psConstants_8h.html	/^<a class="anchor" name="a6" doxytag="psConstants.h::PS_INT_CHECK_EQUALS" ><\/a><p>$/;"	a
+a6	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a6" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a6	docs/html/psImageConvolve_8h.html	/^<a class="anchor" name="a6" doxytag="psImageConvolve.h::psImageConvolve" ><\/a><p>$/;"	a
+a6	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a6" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID" ><\/a><p>$/;"	a
+a6	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a6" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psMemory_NULL_BLOCK" ><\/a><p>$/;"	a
+a6	docs/html/slalib_8h.html	/^<a class="anchor" name="a6" doxytag="slalib.h::slaOapqk" ><\/a><p>$/;"	a
+a60	docs/html/psConstants_8h.html	/^<a class="anchor" name="a60" doxytag="psConstants.h::PS_MIN" ><\/a><p>$/;"	a
+a60	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a60" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED" ><\/a><p>$/;"	a
+a61	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a61" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_SHIFT_NULL" ><\/a><p>$/;"	a
+a62	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a62" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_KERNEL_NULL" ><\/a><p>$/;"	a
+a63	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a63" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH" ><\/a><p>$/;"	a
+a64	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a64" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_FFT_FAILED" ><\/a><p>$/;"	a
+a65	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a65" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED" ><\/a><p>$/;"	a
+a66	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a66" doxytag="psImageErrors.h::PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE" ><\/a><p>$/;"	a
+a67	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a67" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_COEFF_NULL" ><\/a><p>$/;"	a
+a7	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a7" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TABLE_DUPLICATE_ROWS" ><\/a><p>$/;"	a
+a7	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a7" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_SET_NULL" ><\/a><p>$/;"	a
+a7	docs/html/psConstants_8h.html	/^<a class="anchor" name="a7" doxytag="psConstants.h::PS_INT_CHECK_NON_NEGATIVE" ><\/a><p>$/;"	a
+a7	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a7" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_REAL_IMAG_SIZE_MISMATCH" ><\/a><p>$/;"	a
+a7	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a7" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED" ><\/a><p>$/;"	a
+a7	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a7" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE" ><\/a><p>$/;"	a
+a7	docs/html/slalib_8h.html	/^<a class="anchor" name="a7" doxytag="slalib.h::slaAirmas" ><\/a><p>$/;"	a
+a8	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a8" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TYPE_UNKNOWN" ><\/a><p>$/;"	a
+a8	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a8" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE" ><\/a><p>$/;"	a
+a8	docs/html/psConstants_8h.html	/^<a class="anchor" name="a8" doxytag="psConstants.h::PS_INT_CHECK_POSITIVE" ><\/a><p>$/;"	a
+a8	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a8" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED" ><\/a><p>$/;"	a
+a8	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a8" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SUBSECTION_NULL" ><\/a><p>$/;"	a
+a8	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a8" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psMemory_UNDERFLOW" ><\/a><p>$/;"	a
+a8	docs/html/slalib_8h.html	/^<a class="anchor" name="a8" doxytag="slalib.h::fslaAoppa" ><\/a><p>$/;"	a
+a9	docs/html/psAstronomyErrors_8h.html	/^<a class="anchor" name="a9" doxytag="psAstronomyErrors.h::PS_ERRORTEXT_psTime_TYPE_INCORRECT" ><\/a><p>$/;"	a
+a9	docs/html/psCollectionsErrors_8h.html	/^<a class="anchor" name="a9" doxytag="psCollectionsErrors.h::PS_ERRORTEXT_psBitSet_OPERATOR_NULL" ><\/a><p>$/;"	a
+a9	docs/html/psConstants_8h.html	/^<a class="anchor" name="a9" doxytag="psConstants.h::PS_INT_CHECK_ZERO" ><\/a><p>$/;"	a
+a9	docs/html/psDataManipErrors_8h.html	/^<a class="anchor" name="a9" doxytag="psDataManipErrors.h::PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED" ><\/a><p>$/;"	a
+a9	docs/html/psImageErrors_8h.html	/^<a class="anchor" name="a9" doxytag="psImageErrors.h::PS_ERRORTEXT_psImage_SUBSECTION_INVALID" ><\/a><p>$/;"	a
+a9	docs/html/psSysUtilsErrors_8h.html	/^<a class="anchor" name="a9" doxytag="psSysUtilsErrors.h::PS_ERRORTEXT_psMemory_OVERFLOW" ><\/a><p>$/;"	a
+a9	docs/html/slalib_8h.html	/^<a class="anchor" name="a9" doxytag="slalib.h::fslaAopqk" ><\/a><p>$/;"	a
+abberationMag	include/psAstrometry.h	/^    const double abberationMag;        \/\/\/< magnitude of diurnal aberration vector$/;"	m
+abberationMag	src/astronomy/psAstrometry.h	/^    const double abberationMag;        \/\/\/< magnitude of diurnal aberration vector$/;"	m
+airmass	include/psAstrometry.h	/^    const float airmass;               \/\/\/< Airmass, calculated from zenith distance$/;"	m	struct:psExposure
+airmass	src/astronomy/psAstrometry.h	/^    const float airmass;               \/\/\/< Airmass, calculated from zenith distance$/;"	m	struct:psExposure
+allocCallbackCalled	test/sysUtils/tst_psMemory.c	/^static psS32 allocCallbackCalled = 0;$/;"	v	file:
+alphaP	include/psCoord.h	/^    double alphaP;                    \/\/\/< Longitude of the target system pole in the source system$/;"	m
+alphaP	src/astronomy/psCoord.h	/^    double alphaP;                    \/\/\/< Longitude of the target system pole in the source system$/;"	m
+arrayFree	src/collections/psArray.c	/^static void arrayFree(psArray* restrict psArr)$/;"	f	file:
+arrayFree	src/collections/psArray.c	/^static void arrayFree(psArray* restrict psArr);$/;"	p	file:
+azimuth	include/psAstrometry.h	/^    const double azimuth;              \/\/\/< Azimuth$/;"	m	struct:psExposure
+azimuth	src/astronomy/psAstrometry.h	/^    const double azimuth;              \/\/\/< Azimuth$/;"	m	struct:psExposure
+binsize	include/psStats.h	/^    psF64 binsize;             \/\/\/<$/;"	m
+binsize	src/dataManip/psStats.h	/^    psF64 binsize;             \/\/\/<$/;"	m
+bitSetFree	src/collections/psBitSet.c	/^static void bitSetFree(psBitSet* restrict inBitSet)$/;"	f	file:
+bitSetFree	src/collections/psBitSet.c	/^static void bitSetFree(psBitSet* restrict inBitSet);$/;"	p	file:
+bits	include/psBitSet.h	/^    char *bits;                        \/\/\/< Aray of bytes holding bits$/;"	m
+bits	src/collections/psBitSet.h	/^    char *bits;                        \/\/\/< Aray of bytes holding bits$/;"	m
+bounds	include/psStats.h	/^    psVector* bounds;                  \/\/\/< Bounds for the bins (type F32)$/;"	m
+bounds	src/dataManip/psStats.h	/^    psVector* bounds;                  \/\/\/< Bounds for the bins (type F32)$/;"	m
+buckets	include/psHash.h	/^    psHashBucket* *buckets;     \/\/\/< The bucket data.$/;"	m	struct:psHash
+buckets	src/collections/psHash.h	/^    psHashBucket* *buckets;     \/\/\/< The bucket data.$/;"	m	struct:psHash
+build	docs/html/index.html	/^<h2><a class="anchor" name="build">$/;"	a
+cRoot	src/sysUtils/psTrace.c	/^static p_psComponent* cRoot = NULL; \/\/ The root of the trace component$/;"	v	file:
+calcScaleFactors	src/image/psImageStats.c	/^double* calcScaleFactors(psS32 n)$/;"	f
+calloc	include/psMemory.h	/^#define calloc(/;"	d
+calloc	src/sysUtils/psMemory.h	/^#define calloc(/;"	d
+camera	include/psPhotometry.h	/^    const char *camera;         \/\/\/< Camera for photometric system$/;"	m
+camera	src/astronomy/psPhotometry.h	/^    const char *camera;         \/\/\/< Camera for photometric system$/;"	m
+cameraName	include/psAstrometry.h	/^    const char* cameraName;            \/\/\/< name of camera which provided exposure$/;"	m	struct:psExposure
+cameraName	src/astronomy/psAstrometry.h	/^    const char* cameraName;            \/\/\/< name of camera which provided exposure$/;"	m	struct:psExposure
+cellFree	src/astronomy/psAstrometry.c	/^static void cellFree(psCell* cell)$/;"	f	file:
+cells	include/psAstrometry.h	/^    psArray* cells;                    \/\/\/< cells in the chip$/;"	m	struct:psChip
+cells	src/astronomy/psAstrometry.h	/^    psArray* cells;                    \/\/\/< cells in the chip$/;"	m	struct:psChip
+chebPolynomial1DEval	src/dataManip/psFunctions.c	/^static psF32 chebPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)$/;"	f	file:
+chebPolynomial2DEval	src/dataManip/psFunctions.c	/^static psF32 chebPolynomial2DEval(psF32 x, psF32 y, const psPolynomial2D* myPoly)$/;"	f	file:
+chebPolynomial3DEval	src/dataManip/psFunctions.c	/^static psF32 chebPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)$/;"	f	file:
+chebPolynomial4DEval	src/dataManip/psFunctions.c	/^static psF32 chebPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)$/;"	f	file:
+checkForTempDirectory	test/FullUnitTest	/^sub checkForTempDirectory {$/;"	s
+checkForTempDirectory	testbin/FullUnitTest	/^sub checkForTempDirectory {$/;"	s
+checkForVerifiedDirectory	test/FullUnitTest	/^sub checkForVerifiedDirectory {$/;"	s
+checkForVerifiedDirectory	testbin/FullUnitTest	/^sub checkForVerifiedDirectory {$/;"	s
+checkMemBlock	src/sysUtils/psMemory.c	/^static psS32 checkMemBlock(const psMemBlock* m, const char *funcName)$/;"	f	file:
+checkMemBlock	src/sysUtils/psMemory.c	/^static psS32 checkMemBlock(const psMemBlock* m, const char *funcName);$/;"	p	file:
+checkValidImageCoords	src/astronomy/psAstrometry.c	/^static psS32 checkValidImageCoords(double x,$/;"	f	file:
+chi2	include/psAstrometry.h	/^    float chi2;                        \/\/\/< chi^2 of astrometric solution$/;"	m	struct:psFPA
+chi2	src/astronomy/psAstrometry.h	/^    float chi2;                        \/\/\/< chi^2 of astrometric solution$/;"	m	struct:psFPA
+children	include/psImage.h	/^    psArray* children;                 \/\/\/< Children of this region.$/;"	m	struct:psImage
+children	src/image/psImage.h	/^    psArray* children;                 \/\/\/< Children of this region.$/;"	m	struct:psImage
+chipFree	src/astronomy/psAstrometry.c	/^static void chipFree(psChip* chip)$/;"	f	file:
+chips	include/psAstrometry.h	/^    psArray* chips;                    \/\/\/< chips in the focal plane array$/;"	m	struct:psFPA
+chips	src/astronomy/psAstrometry.h	/^    psArray* chips;                    \/\/\/< chips in the focal plane array$/;"	m	struct:psFPA
+cleanString	src/astronomy/psMetadataIO.c	/^char *cleanString(char *inString, psS32 sLen)$/;"	f
+cleanString	src/astronomy/psTime.c	/^static char *cleanString(char *inString, int sLen)$/;"	f	file:
+cleanString	src/astronomy/psTime.c	/^static char *cleanString(char *inString, int sLen);$/;"	p	file:
+cleanString	src/fileUtils/psLookupTable.c	/^static char *cleanString(char *inString, int sLen)$/;"	f	file:
+cleanString	src/fileUtils/psLookupTable.c	/^static char *cleanString(char *inString, int sLen);$/;"	p	file:
+clipIter	include/psStats.h	/^    psS32 clipIter;               \/\/\/< Number of clipping iterations; user input$/;"	m
+clipIter	src/dataManip/psStats.h	/^    psS32 clipIter;               \/\/\/< Number of clipping iterations; user input$/;"	m
+clipSigma	include/psStats.h	/^    psF64 clipSigma;           \/\/\/< Nsigma used for clipping; user input$/;"	m
+clipSigma	src/dataManip/psStats.h	/^    psF64 clipSigma;           \/\/\/< Nsigma used for clipping; user input$/;"	m
+clippedMean	include/psStats.h	/^    psF64 clippedMean;         \/\/\/< Nsigma clipped mean$/;"	m
+clippedMean	src/dataManip/psStats.h	/^    psF64 clippedMean;         \/\/\/< Nsigma clipped mean$/;"	m
+clippedNvalues	include/psStats.h	/^    psS32 clippedNvalues;         \/\/\/< ???$/;"	m
+clippedNvalues	src/dataManip/psStats.h	/^    psS32 clippedNvalues;         \/\/\/< ???$/;"	m
+clippedStdev	include/psStats.h	/^    psF64 clippedStdev;        \/\/\/< standard deviation after clipping$/;"	m
+clippedStdev	src/dataManip/psStats.h	/^    psF64 clippedStdev;        \/\/\/< standard deviation after clipping$/;"	m
+code	include/psError.h	/^    psErrorCode code;                  \/\/\/< class of error$/;"	m
+code	include/psErrorCodes.h	/^    psErrorCode code;                  \/\/\/< An error code$/;"	m
+code	src/sysUtils/psError.h	/^    psErrorCode code;                  \/\/\/< class of error$/;"	m
+code	src/sysUtils/psErrorCodes.h	/^    psErrorCode code;                  \/\/\/< An error code$/;"	m
+coeff	include/psFunctions.h	/^    psF32 ****coeff;                   \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF32 ***coeff;                    \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF32 **coeff;                     \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF32 *coeff;                      \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF64 ****coeff;                  \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF64 ***coeff;                   \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF64 **coeff;                    \/\/\/< Coefficients$/;"	m
+coeff	include/psFunctions.h	/^    psF64 *coeff;                     \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF32 ****coeff;                   \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF32 ***coeff;                    \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF32 **coeff;                     \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF32 *coeff;                      \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF64 ****coeff;                  \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF64 ***coeff;                   \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF64 **coeff;                    \/\/\/< Coefficients$/;"	m
+coeff	src/dataManip/psFunctions.h	/^    psF64 *coeff;                     \/\/\/< Coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF32 ****coeffErr;                \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF32 ***coeffErr;                 \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF32 **coeffErr;                  \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF32 *coeffErr;                   \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF64 ****coeffErr;               \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF64 ***coeffErr;                \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF64 **coeffErr;                 \/\/\/< Error in coefficients$/;"	m
+coeffErr	include/psFunctions.h	/^    psF64 *coeffErr;                  \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF32 ****coeffErr;                \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF32 ***coeffErr;                 \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF32 **coeffErr;                  \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF32 *coeffErr;                   \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF64 ****coeffErr;               \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF64 ***coeffErr;                \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF64 **coeffErr;                 \/\/\/< Error in coefficients$/;"	m
+coeffErr	src/dataManip/psFunctions.h	/^    psF64 *coeffErr;                  \/\/\/< Error in coefficients$/;"	m
+col0	include/psAstrometry.h	/^    const psS32 col0;                    \/\/\/< Offset from the left of chip.$/;"	m
+col0	include/psImage.h	/^    const psS32 col0;                    \/\/\/< Column position relative to parent.$/;"	m	struct:psImage
+col0	src/astronomy/psAstrometry.h	/^    const psS32 col0;                    \/\/\/< Offset from the left of chip.$/;"	m
+col0	src/image/psImage.h	/^    const psS32 col0;                    \/\/\/< Column position relative to parent.$/;"	m	struct:psImage
+colBins	include/psAstrometry.h	/^    const psU32 colBins;        \/\/\/< Amount of binning in x-dimension$/;"	m
+colBins	src/astronomy/psAstrometry.h	/^    const psU32 colBins;        \/\/\/< Amount of binning in x-dimension$/;"	m
+colorMinus	include/psAstrometry.h	/^    psPhotSystem* colorMinus;          \/\/\/< Color reference$/;"	m	struct:psFPA
+colorMinus	src/astronomy/psAstrometry.h	/^    psPhotSystem* colorMinus;          \/\/\/< Color reference$/;"	m	struct:psFPA
+colorPlus	include/psAstrometry.h	/^    psPhotSystem* colorPlus;           \/\/\/< Color reference$/;"	m	struct:psFPA
+colorPlus	src/astronomy/psAstrometry.h	/^    psPhotSystem* colorPlus;           \/\/\/< Color reference$/;"	m	struct:psFPA
+comment	include/psMetadata.h	/^    char *comment;                     \/\/\/< Optional comment ("", not NULL).$/;"	m	struct:psMetadataItem
+comment	src/astronomy/psMetadata.h	/^    char *comment;                     \/\/\/< Optional comment ("", not NULL).$/;"	m	struct:psMetadataItem
+compareStream	test/FullUnitTest	/^sub compareStream {$/;"	s
+compareStream	test/runTest	/^sub compareStream {$/;"	s
+compareStream	testbin/FullUnitTest	/^sub compareStream {$/;"	s
+compareStream	testbin/runTest	/^sub compareStream {$/;"	s
+componentAdd	src/sysUtils/psTrace.c	/^static psBool componentAdd(const char *addNodeName, psS32 level)$/;"	f	file:
+componentAlloc	src/sysUtils/psTrace.c	/^static p_psComponent* componentAlloc(const char *name, psS32 level)$/;"	f	file:
+componentAlloc	src/sysUtils/psTrace.c	/^static p_psComponent* componentAlloc(const char *name, psS32 level);$/;"	p	file:
+componentFree	src/sysUtils/psTrace.c	/^static void componentFree(p_psComponent* comp)$/;"	f	file:
+componentFree	src/sysUtils/psTrace.c	/^static void componentFree(p_psComponent* comp);$/;"	p	file:
+convertFitsToPsType	src/fileUtils/psFits.c	/^static psElemType convertFitsToPsType(int datatype)$/;"	f	file:
+convertPsTypeToBinaryTForm	src/fileUtils/psFits.c	/^static bool convertPsTypeToBinaryTForm(psElemType type, char** fitsType)$/;"	f	file:
+convertPsTypeToFits	src/fileUtils/psFits.c	/^static bool convertPsTypeToFits(psElemType type, int* bitPix, double* bZero, int* dataType)$/;"	f	file:
+cosDeltaP	include/psCoord.h	/^    double cosDeltaP;                 \/\/\/< Cosine of target pole latitude in the source system$/;"	m
+cosDeltaP	src/astronomy/psCoord.h	/^    double cosDeltaP;                 \/\/\/< Cosine of target pole latitude in the source system$/;"	m
+cosLat	include/psAstrometry.h	/^    const double cosLat;               \/\/\/< cosine of geodetic latitude$/;"	m
+cosLat	src/astronomy/psAstrometry.h	/^    const double cosLat;               \/\/\/< cosine of geodetic latitude$/;"	m
+createChebyshevPolys	src/dataManip/psFunctions.c	/^static psPolynomial1D **createChebyshevPolys(psS32 maxChebyPoly)$/;"	f	file:
+currentId	test/collections/tst_psHash03.c	/^psS32 currentId = 0;$/;"	v
+cursor	include/psList.h	/^psListElem* cursor;                \/\/\/< current cursor position$/;"	m
+cursor	src/collections/psList.h	/^psListElem* cursor;                \/\/\/< current cursor position$/;"	m
+d	include/psCoord.h	/^    double d;                   \/\/\/< Dec$/;"	m	struct:psSphere
+d	src/astronomy/psCoord.h	/^    double d;                   \/\/\/< Dec$/;"	m	struct:psSphere
+dChebPolynomial1DEval	src/dataManip/psFunctions.c	/^static psF64 dChebPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)$/;"	f	file:
+dChebPolynomial2DEval	src/dataManip/psFunctions.c	/^static psF64 dChebPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)$/;"	f	file:
+dChebPolynomial3DEval	src/dataManip/psFunctions.c	/^static psF64 dChebPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)$/;"	f	file:
+dChebPolynomial4DEval	src/dataManip/psFunctions.c	/^static psF64 dChebPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)$/;"	f	file:
+dErr	include/psCoord.h	/^    double dErr;                \/\/\/< Error in Dec$/;"	m	struct:psSphere
+dErr	src/astronomy/psCoord.h	/^    double dErr;                \/\/\/< Error in Dec$/;"	m	struct:psSphere
+dOrdPolynomial1DEval	src/dataManip/psFunctions.c	/^static psF64 dOrdPolynomial1DEval(psF64 x, const psDPolynomial1D* myPoly)$/;"	f	file:
+dOrdPolynomial2DEval	src/dataManip/psFunctions.c	/^static psF64 dOrdPolynomial2DEval(psF64 x, psF64 y, const psDPolynomial2D* myPoly)$/;"	f	file:
+dOrdPolynomial3DEval	src/dataManip/psFunctions.c	/^static psF64 dOrdPolynomial3DEval(psF64 x, psF64 y, psF64 z, const psDPolynomial3D* myPoly)$/;"	f	file:
+dOrdPolynomial4DEval	src/dataManip/psFunctions.c	/^static psF64 dOrdPolynomial4DEval(psF64 w, psF64 x, psF64 y, psF64 z, const psDPolynomial4D* myPoly)$/;"	f	file:
+dPolynomial1DFree	src/dataManip/psFunctions.c	/^static void dPolynomial1DFree(psDPolynomial1D* myPoly)$/;"	f	file:
+dPolynomial1DFree	src/dataManip/psFunctions.c	/^static void dPolynomial1DFree(psDPolynomial1D* myPoly);$/;"	p	file:
+dPolynomial2DFree	src/dataManip/psFunctions.c	/^static void dPolynomial2DFree(psDPolynomial2D* myPoly)$/;"	f	file:
+dPolynomial2DFree	src/dataManip/psFunctions.c	/^static void dPolynomial2DFree(psDPolynomial2D* myPoly);$/;"	p	file:
+dPolynomial3DFree	src/dataManip/psFunctions.c	/^static void dPolynomial3DFree(psDPolynomial3D* myPoly)$/;"	f	file:
+dPolynomial3DFree	src/dataManip/psFunctions.c	/^static void dPolynomial3DFree(psDPolynomial3D* myPoly);$/;"	p	file:
+dPolynomial4DFree	src/dataManip/psFunctions.c	/^static void dPolynomial4DFree(psDPolynomial4D* myPoly)$/;"	f	file:
+dPolynomial4DFree	src/dataManip/psFunctions.c	/^static void dPolynomial4DFree(psDPolynomial4D* myPoly);$/;"	p	file:
+data	include/psArray.h	/^    psPtr* data;                \/\/\/< An Array of pointer elements$/;"	m
+data	include/psHash.h	/^    psPtr data;                 \/\/\/< the data itself$/;"	m	struct:psHashBucket
+data	include/psImage.h	/^    } data;                            \/\/\/< Union for data types.$/;"	m	struct:psImage
+data	include/psList.h	/^    psPtr data;                        \/\/\/< real data item$/;"	m	struct:psListElem
+data	include/psMetadata.h	/^    } data;                            \/\/\/< Union for data types.$/;"	m	struct:psMetadataItem
+data	include/psScalar.h	/^    } data;                     \/\/\/< Union for data types.$/;"	m
+data	include/psVector.h	/^    } data;                     \/\/\/< Union for data types.$/;"	m
+data	src/astronomy/psMetadata.h	/^    } data;                            \/\/\/< Union for data types.$/;"	m	struct:psMetadataItem
+data	src/collections/psArray.h	/^    psPtr* data;                \/\/\/< An Array of pointer elements$/;"	m
+data	src/collections/psHash.h	/^    psPtr data;                 \/\/\/< the data itself$/;"	m	struct:psHashBucket
+data	src/collections/psList.h	/^    psPtr data;                        \/\/\/< real data item$/;"	m	struct:psListElem
+data	src/collections/psScalar.h	/^    } data;                     \/\/\/< Union for data types.$/;"	m
+data	src/collections/psVector.h	/^    } data;                     \/\/\/< Union for data types.$/;"	m
+data	src/image/psImage.h	/^    } data;                            \/\/\/< Union for data types.$/;"	m	struct:psImage
+deadBlockList	src/sysUtils/psMemory.c	/^static psMemBlock* deadBlockList;       \/\/ a place to put dead memBlocks in debug mode.$/;"	v	file:
+dec	include/psAstrometry.h	/^    const double dec;                  \/\/\/< Telescope boresight, declination$/;"	m	struct:psExposure
+dec	src/astronomy/psAstrometry.h	/^    const double dec;                  \/\/\/< Telescope boresight, declination$/;"	m	struct:psExposure
+description	include/psErrorCodes.h	/^    const char *description;           \/\/\/< the associated description$/;"	m
+description	src/sysUtils/psErrorCodes.h	/^    const char *description;           \/\/\/< the associated description$/;"	m
+detector	include/psPhotometry.h	/^    const char *detector;       \/\/\/< Detector used for photometric system$/;"	m
+detector	src/astronomy/psPhotometry.h	/^    const char *detector;       \/\/\/< Detector used for photometric system$/;"	m
+dimen	include/psType.h	/^    psDimen dimen;              \/\/\/< Dimensionality.$/;"	m
+dimen	src/sysUtils/psType.h	/^    psDimen dimen;              \/\/\/< Dimensionality.$/;"	m
+doGetTraceLevel	src/sysUtils/psTrace.c	/^static psS32 doGetTraceLevel(const char *aname)$/;"	f	file:
+doHashWork	src/collections/psHash.c	/^static psPtr doHashWork(psHash* table, const char *key, psPtr data, psBool remove$/;"	p	file:
+doHashWork	src/collections/psHash.c	/^static psPtr doHashWork(psHash* table,$/;"	f	file:
+doPrintTraceLevels	src/sysUtils/psTrace.c	/^static void doPrintTraceLevels(const p_psComponent* comp,$/;"	f	file:
+doc	docs/html/index.html	/^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.<h2><a class="anchor" name="doc">$/;"	a
+domains	include/psFunctions.h	/^    psF32 *domains;               \/\/\/< The boundaries between each spline piece.  Size is n+1.$/;"	m
+domains	src/dataManip/psFunctions.h	/^    psF32 *domains;               \/\/\/< The boundaries between each spline piece.  Size is n+1.$/;"	m
+dst	include/psPhotometry.h	/^    psPhotSystem dst;           \/\/\/< Destination photometric system$/;"	m
+dst	src/astronomy/psPhotometry.h	/^    psPhotSystem dst;           \/\/\/< Destination photometric system$/;"	m
+dynamicErrorCodes	src/sysUtils/psErrorCodes.c	/^static psList* dynamicErrorCodes = NULL;$/;"	v	file:
+endblock	include/psMemory.h	/^    const psPtr endblock;              \/\/\/< initialised to p_psMEMMAGIC$/;"	m	struct:psMemBlock
+endblock	src/sysUtils/psMemory.h	/^    const psPtr endblock;              \/\/\/< initialised to p_psMEMMAGIC$/;"	m	struct:psMemBlock
+errFree	src/sysUtils/psError.c	/^static void errFree(psErr* err)$/;"	f	file:
+errorStack	src/sysUtils/psError.c	/^static psErr* errorStack[MAX_ERROR_STACK_SIZE];$/;"	v	file:
+errorStackSize	src/sysUtils/psError.c	/^static psU32 errorStackSize = 0;$/;"	v	file:
+errorStrSearch	test/FullUnitTest	/^sub errorStrSearch {$/;"	s
+errorStrSearch	test/runTest	/^sub errorStrSearch {$/;"	s
+errorStrSearch	testbin/FullUnitTest	/^sub errorStrSearch {$/;"	s
+errorStrSearch	testbin/runTest	/^sub errorStrSearch {$/;"	s
+executeTestDrivers	test/FullUnitTest	/^sub executeTestDrivers {$/;"	s
+executeTestDrivers	testbin/FullUnitTest	/^sub executeTestDrivers {$/;"	s
+exhaustedCallbackCalled	test/sysUtils/tst_psMemory.c	/^static psS32 exhaustedCallbackCalled = 0;$/;"	v	file:
+expectedParm	test/dataManip/tst_psMinimize05.c	/^float expectedParm[NUM_PARAMS];$/;"	v
+expectedParm	test/dataManip/tst_psMinimize06.c	/^float expectedParm[NUM_PARAMS];$/;"	v
+expectedParm	test/dataManip/tst_psMinimize07.c	/^float expectedParm[NUM_PARAMS];$/;"	v
+expectedReturn	include/psTest.h	/^    psS32       expectedReturn;$/;"	m
+expectedReturn	test/psTest.h	/^    psS32       expectedReturn;$/;"	m
+exposure	include/psAstrometry.h	/^    const struct psExposure* exposure; \/\/\/< information about this exposure$/;"	m	struct:psFPA
+exposure	src/astronomy/psAstrometry.h	/^    const struct psExposure* exposure; \/\/\/< information about this exposure$/;"	m	struct:psFPA
+exposureFree	src/astronomy/psAstrometry.c	/^static void exposureFree(psExposure* exp)$/;"	f	file:
+exposureTime	include/psAstrometry.h	/^    const float exposureTime;          \/\/\/< Exposure time$/;"	m	struct:psExposure
+exposureTime	src/astronomy/psAstrometry.h	/^    const float exposureTime;          \/\/\/< Exposure time$/;"	m	struct:psExposure
+extinstall	docs/html/index.html	/^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 &lt;<a class="el" href="pslib_8h.html">pslib.h<\/a>&gt; and linking using the '-lpslib' option while linking.<h2><a class="anchor" name="extinstall">$/;"	a
+fcn	include/psTest.h	/^    testFcn     fcn;$/;"	m
+fcn	test/psTest.h	/^    testFcn     fcn;$/;"	m
+file	include/psMemory.h	/^    const char *file;                  \/\/\/< set from __FILE__ in e.g. p_psAlloc$/;"	m	struct:psMemBlock
+file	src/sysUtils/psMemory.h	/^    const char *file;                  \/\/\/< set from __FILE__ in e.g. p_psAlloc$/;"	m	struct:psMemBlock
+fileName	include/psLookupTable.h	/^    const char *fileName;              \/\/\/< Name of file with table$/;"	m
+fileName	src/fileUtils/psLookupTable.h	/^    const char *fileName;              \/\/\/< Name of file with table$/;"	m
+filename	src/fileUtils/psFits.h	/^    const char* filename;              \/\/\/< the filename of the fits file$/;"	m
+filter	include/psPhotometry.h	/^    const char *filter;         \/\/\/< Filter used for photometric system$/;"	m
+filter	src/astronomy/psPhotometry.h	/^    const char *filter;         \/\/\/< Filter used for photometric system$/;"	m
+filterStdFiles	test/FullUnitTest	/^sub filterStdFiles {$/;"	s
+filterStdFiles	testbin/FullUnitTest	/^sub filterStdFiles {$/;"	s
+fitQuadraticSearchForYThenReturnX	src/dataManip/psStats.c	/^psF32 fitQuadraticSearchForYThenReturnX(psVector *xVec,$/;"	f
+fitsFree	src/fileUtils/psFits.c	/^static void fitsFree(psFits* fits)$/;"	f	file:
+fixedPatternFree	src/astronomy/psAstrometry.c	/^static void fixedPatternFree(psFixedPattern* fp)$/;"	f	file:
+free	include/psMemory.h	/^#define free(/;"	d
+free	src/sysUtils/psMemory.h	/^#define free(/;"	d
+freeCallbackCalled	test/sysUtils/tst_psMemory.c	/^static psS32 freeCallbackCalled = 0;$/;"	v	file:
+freeErrorDescription	src/sysUtils/psErrorCodes.c	/^static void freeErrorDescription(psErrorDescription* err)$/;"	f	file:
+freeFcn	include/psMemory.h	/^    psFreeFcn freeFcn;                 \/\/\/< deallocator.  If NULL, use generic deallocation.$/;"	m	struct:psMemBlock
+freeFcn	src/sysUtils/psMemory.h	/^    psFreeFcn freeFcn;                 \/\/\/< deallocator.  If NULL, use generic deallocation.$/;"	m	struct:psMemBlock
+freeKernel	src/image/psImageConvolve.c	/^static void freeKernel(psKernel* ptr);$/;"	p	file:
+freeKernel	src/image/psImageConvolve.c	/^void freeKernel(psKernel* ptr)$/;"	f
+fromChip	include/psAstrometry.h	/^    psPlaneTransform* fromChip;        \/\/\/< transformations from chip to cell coordinates$/;"	m
+fromChip	src/astronomy/psAstrometry.h	/^    psPlaneTransform* fromChip;        \/\/\/< transformations from chip to cell coordinates$/;"	m
+fromFPA	include/psAstrometry.h	/^    psPlaneTransform* fromFPA;         \/\/\/< transformation from FPA to chip coordinates$/;"	m	struct:psChip
+fromFPA	src/astronomy/psAstrometry.h	/^    psPlaneTransform* fromFPA;         \/\/\/< transformation from FPA to chip coordinates$/;"	m	struct:psChip
+fromTangentPlane	include/psAstrometry.h	/^    psPlaneDistort* fromTangentPlane;  \/\/\/< transformation from tangent plane to focal plane$/;"	m	struct:psFPA
+fromTangentPlane	src/astronomy/psAstrometry.h	/^    psPlaneDistort* fromTangentPlane;  \/\/\/< transformation from tangent plane to focal plane$/;"	m	struct:psFPA
+fslaAirmas	include/slalib.h	/^#define fslaAirmas /;"	d
+fslaAirmas	include/slalib.h	/^extern double fslaAirmas($/;"	p
+fslaAirmas	src/astronomy/slalib.h	/^#define fslaAirmas /;"	d
+fslaAirmas	src/astronomy/slalib.h	/^extern double fslaAirmas($/;"	p
+fslaAoppa	include/slalib.h	/^#define fslaAoppa /;"	d
+fslaAoppa	include/slalib.h	/^extern void fslaAoppa($/;"	p
+fslaAoppa	src/astronomy/slalib.h	/^#define fslaAoppa /;"	d
+fslaAoppa	src/astronomy/slalib.h	/^extern void fslaAoppa($/;"	p
+fslaAopqk	include/slalib.h	/^#define fslaAopqk /;"	d
+fslaAopqk	include/slalib.h	/^extern void fslaAopqk($/;"	p
+fslaAopqk	src/astronomy/slalib.h	/^#define fslaAopqk /;"	d
+fslaAopqk	src/astronomy/slalib.h	/^extern void fslaAopqk($/;"	p
+fslaOapqk	include/slalib.h	/^#define fslaOapqk /;"	d
+fslaOapqk	include/slalib.h	/^extern void fslaOapqk($/;"	p
+fslaOapqk	src/astronomy/slalib.h	/^#define fslaOapqk /;"	d
+fslaOapqk	src/astronomy/slalib.h	/^extern void fslaOapqk($/;"	p
+ga0	docs/html/group__Array.html	/^<a class="anchor" name="ga0" doxytag="psArray.h::psArrayAlloc" ><\/a><p>$/;"	a
+ga0	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga0" doxytag="psAstrometry.h::psChip" ><\/a><p>$/;"	a
+ga0	docs/html/group__BitSet.html	/^<a class="anchor" name="ga0" doxytag="psBitSet.h::psBitSetAlloc" ><\/a><p>$/;"	a
+ga0	docs/html/group__Compare.html	/^<a class="anchor" name="ga0" doxytag="psCompare.h::psComparePtrFcn" ><\/a><p>$/;"	a
+ga0	docs/html/group__Configure.html	/^<a class="anchor" name="ga0" doxytag="psConfigure.h::psLibVersion" ><\/a><p>$/;"	a
+ga0	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga0" doxytag="psCoord.h::psSphere" ><\/a><p>$/;"	a
+ga0	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga0" doxytag="psType.h::psU8" ><\/a><p>$/;"	a
+ga0	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga0" doxytag="psAbort.h::psAbort" ><\/a><p>$/;"	a
+ga0	docs/html/group__HashTable.html	/^<a class="anchor" name="ga0" doxytag="psHash.h::psHashBucket" ><\/a><p>$/;"	a
+ga0	docs/html/group__Image.html	/^<a class="anchor" name="ga0" doxytag="psImage.h::psImage" ><\/a><p>$/;"	a
+ga0	docs/html/group__ImageIO.html	/^<a class="anchor" name="ga0" doxytag="psImageIO.h::psImageReadSection" ><\/a><p>$/;"	a
+ga0	docs/html/group__ImageStats.html	/^<a class="anchor" name="ga0" doxytag="psImageStats.h::psImageStats" ><\/a><p>$/;"	a
+ga0	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga0" doxytag="psList.h::psListElem" ><\/a><p>$/;"	a
+ga0	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga0" doxytag="psTrace.h::p_psComponent" ><\/a><p>$/;"	a
+ga0	docs/html/group__Math.html	/^<a class="anchor" name="ga0" doxytag="psRandom.h::psRandomAlloc" ><\/a><p>$/;"	a
+ga0	docs/html/group__Matrix.html	/^<a class="anchor" name="ga0" doxytag="psMatrix.h::psMatrixLUD" ><\/a><p>$/;"	a
+ga0	docs/html/group__MatrixVectorArithmetic.html	/^<a class="anchor" name="ga0" doxytag="psMatrixVectorArithmetic.h::psBinaryOp" ><\/a><p>$/;"	a
+ga0	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga0" doxytag="psMemory.h::psMemoryId" ><\/a><p>$/;"	a
+ga0	docs/html/group__Metadata.html	/^<a class="anchor" name="ga0" doxytag="psMetadata.h::psMetadata" ><\/a><p>$/;"	a
+ga0	docs/html/group__Scalar.html	/^<a class="anchor" name="ga0" doxytag="psScalar.h::psScalarAlloc" ><\/a><p>$/;"	a
+ga0	docs/html/group__Stats.html	/^<a class="anchor" name="ga0" doxytag="psMinimize.h::psMinimizeLMChi2Func" ><\/a><p>$/;"	a
+ga0	docs/html/group__SysUtils.html	/^<a class="anchor" name="ga0" doxytag="psString.h::psStringCopy" ><\/a><p>$/;"	a
+ga0	docs/html/group__Time.html	/^<a class="anchor" name="ga0" doxytag="psTime.h::psTime" ><\/a><p>$/;"	a
+ga0	docs/html/group__Transform.html	/^<a class="anchor" name="ga0" doxytag="psImageFFT.h::psImageFFT" ><\/a><p>$/;"	a
+ga0	docs/html/group__Vector.html	/^<a class="anchor" name="ga0" doxytag="psVector.h::psVectorAlloc" ><\/a><p>$/;"	a
+ga0	docs/html/group__memCallback.html	/^<a class="anchor" name="ga0" doxytag="psMemory.h::psMemAllocateCallback" ><\/a><p>$/;"	a
+ga0	docs/html/group__memRefCount.html	/^<a class="anchor" name="ga0" doxytag="psMemory.h::psMemGetRefCounter" ><\/a><p>$/;"	a
+ga0	docs/html/group__memTracing.html	/^<a class="anchor" name="ga0" doxytag="psMemory.h::psMemCheckLeaks" ><\/a><p>$/;"	a
+ga1	docs/html/group__Array.html	/^<a class="anchor" name="ga1" doxytag="psArray.h::psArrayRealloc" ><\/a><p>$/;"	a
+ga1	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga1" doxytag="psAstrometry.h::psFPA" ><\/a><p>$/;"	a
+ga1	docs/html/group__BitSet.html	/^<a class="anchor" name="ga1" doxytag="psBitSet.h::psBitSetSet" ><\/a><p>$/;"	a
+ga1	docs/html/group__Compare.html	/^<a class="anchor" name="ga1" doxytag="psCompare.h::psCompareFcn" ><\/a><p>$/;"	a
+ga1	docs/html/group__Configure.html	/^<a class="anchor" name="ga1" doxytag="psConfigure.h::psLibInit" ><\/a><p>$/;"	a
+ga1	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga1" doxytag="psCoord.h::psPlaneTransformAlloc" ><\/a><p>$/;"	a
+ga1	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga1" doxytag="psType.h::psU16" ><\/a><p>$/;"	a
+ga1	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga1" doxytag="psError.h::psErrorGet" ><\/a><p>$/;"	a
+ga1	docs/html/group__HashTable.html	/^<a class="anchor" name="ga1" doxytag="psHash.h::psHash" ><\/a><p>$/;"	a
+ga1	docs/html/group__Image.html	/^<a class="anchor" name="ga1" doxytag="psImage.h::psImageAlloc" ><\/a><p>$/;"	a
+ga1	docs/html/group__ImageIO.html	/^<a class="anchor" name="ga1" doxytag="psImageIO.h::psImageWriteSection" ><\/a><p>$/;"	a
+ga1	docs/html/group__ImageStats.html	/^<a class="anchor" name="ga1" doxytag="psImageStats.h::psImageHistogram" ><\/a><p>$/;"	a
+ga1	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga1" doxytag="psList.h::psListAlloc" ><\/a><p>$/;"	a
+ga1	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga1" doxytag="psLogMsg.h::psLogSetDestination" ><\/a><p>$/;"	a
+ga1	docs/html/group__Math.html	/^<a class="anchor" name="ga1" doxytag="psRandom.h::psRandomReset" ><\/a><p>$/;"	a
+ga1	docs/html/group__Matrix.html	/^<a class="anchor" name="ga1" doxytag="psMatrix.h::psMatrixLUSolve" ><\/a><p>$/;"	a
+ga1	docs/html/group__MatrixVectorArithmetic.html	/^<a class="anchor" name="ga1" doxytag="psMatrixVectorArithmetic.h::psUnaryOp" ><\/a><p>$/;"	a
+ga1	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga1" doxytag="psMemory.h::psReferenceCount" ><\/a><p>$/;"	a
+ga1	docs/html/group__Metadata.html	/^<a class="anchor" name="ga1" doxytag="psMetadata.h::psMetadataItem" ><\/a><p>$/;"	a
+ga1	docs/html/group__Scalar.html	/^<a class="anchor" name="ga1" doxytag="psScalar.h::psScalarCopy" ><\/a><p>$/;"	a
+ga1	docs/html/group__Stats.html	/^<a class="anchor" name="ga1" doxytag="psMinimize.h::psMinimizePowellFunc" ><\/a><p>$/;"	a
+ga1	docs/html/group__SysUtils.html	/^<a class="anchor" name="ga1" doxytag="psString.h::psStringNCopy" ><\/a><p>$/;"	a
+ga1	docs/html/group__Time.html	/^<a class="anchor" name="ga1" doxytag="psTime.h::psTimeInit" ><\/a><p>$/;"	a
+ga1	docs/html/group__Transform.html	/^<a class="anchor" name="ga1" doxytag="psImageFFT.h::psImageReal" ><\/a><p>$/;"	a
+ga1	docs/html/group__Vector.html	/^<a class="anchor" name="ga1" doxytag="psVector.h::psVectorRealloc" ><\/a><p>$/;"	a
+ga1	docs/html/group__memCallback.html	/^<a class="anchor" name="ga1" doxytag="psMemory.h::psMemFreeCallback" ><\/a><p>$/;"	a
+ga1	docs/html/group__memRefCount.html	/^<a class="anchor" name="ga1" doxytag="psMemory.h::psMemIncrRefCounter" ><\/a><p>$/;"	a
+ga1	docs/html/group__memTracing.html	/^<a class="anchor" name="ga1" doxytag="psMemory.h::psMemCheckCorruption" ><\/a><p>$/;"	a
+ga10	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga10" doxytag="psAstrometry.h::psGrommitAlloc" ><\/a><p>$/;"	a
+ga10	docs/html/group__Compare.html	/^<a class="anchor" name="ga10" doxytag="psCompare.h::psCompareF32Ptr" ><\/a><p>$/;"	a
+ga10	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga10" doxytag="psCoord.h::psSphereTransformGalaticToICRS" ><\/a><p>$/;"	a
+ga10	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga10" doxytag="psType.h::psC32" ><\/a><p>$/;"	a
+ga10	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga10" doxytag="psErrorCodes.h::psErrorRegister" ><\/a><p>$/;"	a
+ga10	docs/html/group__Image.html	/^<a class="anchor" name="ga10" doxytag="psImageExtraction.h::psImageTrim" ><\/a><p>$/;"	a
+ga10	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga10" doxytag="psList.h::psListGetNext" ><\/a><p>$/;"	a
+ga10	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga10" doxytag="psTrace.h::psTraceFree" ><\/a><p>$/;"	a
+ga10	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga10" doxytag="psMemory.h::psFree" ><\/a><p>$/;"	a
+ga10	docs/html/group__Metadata.html	/^<a class="anchor" name="ga10" doxytag="psMetadata.h::psMetadataLookupS32" ><\/a><p>$/;"	a
+ga10	docs/html/group__Stats.html	/^<a class="anchor" name="ga10" doxytag="psFunctions.h::psPolynomial2DEval" ><\/a><p>$/;"	a
+ga10	docs/html/group__Time.html	/^<a class="anchor" name="ga10" doxytag="psTime.h::psTimeLeapseconds" ><\/a><p>$/;"	a
+ga10	docs/html/group__Transform.html	/^<a class="anchor" name="ga10" doxytag="psVectorFFT.h::psVectorConjugate" ><\/a><p>$/;"	a
+ga10	docs/html/group__memCallback.html	/^<a class="anchor" name="ga10" doxytag="psMemory.h::psMemFreeCallbackSetID" ><\/a><p>$/;"	a
+ga11	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga11" doxytag="psAstrometry.h::psCellInFPA" ><\/a><p>$/;"	a
+ga11	docs/html/group__Compare.html	/^<a class="anchor" name="ga11" doxytag="psCompare.h::psCompareF64Ptr" ><\/a><p>$/;"	a
+ga11	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga11" doxytag="psCoord.h::psProject" ><\/a><p>$/;"	a
+ga11	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga11" doxytag="psType.h::psC64" ><\/a><p>$/;"	a
+ga11	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga11" doxytag="psErrorCodes.h::p_psErrorUnregister" ><\/a><p>$/;"	a
+ga11	docs/html/group__Image.html	/^<a class="anchor" name="ga11" doxytag="psImageExtraction.h::psImageSlice" ><\/a><p>$/;"	a
+ga11	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga11" doxytag="psList.h::psListGetPrevious" ><\/a><p>$/;"	a
+ga11	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga11" doxytag="psTrace.h::psTracePrintLevels" ><\/a><p>$/;"	a
+ga11	docs/html/group__Metadata.html	/^<a class="anchor" name="ga11" doxytag="psMetadata.h::psMetadataLookupPtr" ><\/a><p>$/;"	a
+ga11	docs/html/group__Stats.html	/^<a class="anchor" name="ga11" doxytag="psFunctions.h::psPolynomial3DEval" ><\/a><p>$/;"	a
+ga11	docs/html/group__Time.html	/^<a class="anchor" name="ga11" doxytag="psTime.h::psTimeToJD" ><\/a><p>$/;"	a
+ga11	docs/html/group__Transform.html	/^<a class="anchor" name="ga11" doxytag="psVectorFFT.h::psVectorPowerSpectrum" ><\/a><p>$/;"	a
+ga12	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga12" doxytag="psAstrometry.h::psChipInFPA" ><\/a><p>$/;"	a
+ga12	docs/html/group__Compare.html	/^<a class="anchor" name="ga12" doxytag="psCompare.h::psCompareDescendingS8Ptr" ><\/a><p>$/;"	a
+ga12	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga12" doxytag="psCoord.h::psDeproject" ><\/a><p>$/;"	a
+ga12	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga12" doxytag="psType.h::psPtr" ><\/a><p>$/;"	a
+ga12	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga12" doxytag="psError.h::psError" ><\/a><p>$/;"	a
+ga12	docs/html/group__Image.html	/^<a class="anchor" name="ga12" doxytag="psImageExtraction.h::psImageCut" ><\/a><p>$/;"	a
+ga12	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga12" doxytag="psList.h::psListToArray" ><\/a><p>$/;"	a
+ga12	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga12" doxytag="psTrace.h::psTraceSetDestination" ><\/a><p>$/;"	a
+ga12	docs/html/group__Metadata.html	/^<a class="anchor" name="ga12" doxytag="psMetadata.h::psMetadataGet" ><\/a><p>$/;"	a
+ga12	docs/html/group__Stats.html	/^<a class="anchor" name="ga12" doxytag="psFunctions.h::psPolynomial4DEval" ><\/a><p>$/;"	a
+ga12	docs/html/group__Time.html	/^<a class="anchor" name="ga12" doxytag="psTime.h::psTimeToMJD" ><\/a><p>$/;"	a
+ga12	docs/html/group__Transform.html	/^<a class="anchor" name="ga12" doxytag="psVectorFFT.h::psFFTFlags" ><\/a><p>$/;"	a
+ga13	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga13" doxytag="psAstrometry.h::psCellInChip" ><\/a><p>$/;"	a
+ga13	docs/html/group__Compare.html	/^<a class="anchor" name="ga13" doxytag="psCompare.h::psCompareDescendingS16Ptr" ><\/a><p>$/;"	a
+ga13	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga13" doxytag="psCoord.h::psSphereGetOffset" ><\/a><p>$/;"	a
+ga13	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga13" doxytag="psType.h::psBool" ><\/a><p>$/;"	a
+ga13	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga13" doxytag="psErrorCodes.h::psErrorCode" ><\/a><p>$/;"	a
+ga13	docs/html/group__Image.html	/^<a class="anchor" name="ga13" doxytag="psImageExtraction.h::psImageRadialCut" ><\/a><p>$/;"	a
+ga13	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga13" doxytag="psList.h::psArrayToList" ><\/a><p>$/;"	a
+ga13	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga13" doxytag="psLogMsg.h::@0" ><\/a><p>$/;"	a
+ga13	docs/html/group__Metadata.html	/^<a class="anchor" name="ga13" doxytag="psMetadataIO.h::psMetadataItemPrint" ><\/a><p>$/;"	a
+ga13	docs/html/group__Stats.html	/^<a class="anchor" name="ga13" doxytag="psFunctions.h::psPolynomial1DEvalVector" ><\/a><p>$/;"	a
+ga13	docs/html/group__Time.html	/^<a class="anchor" name="ga13" doxytag="psTime.h::psTimeToISOTime" ><\/a><p>$/;"	a
+ga14	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga14" doxytag="psAstrometry.h::psCoordCellToChip" ><\/a><p>$/;"	a
+ga14	docs/html/group__Compare.html	/^<a class="anchor" name="ga14" doxytag="psCompare.h::psCompareDescendingS32Ptr" ><\/a><p>$/;"	a
+ga14	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga14" doxytag="psCoord.h::psSphereSetOffset" ><\/a><p>$/;"	a
+ga14	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga14" doxytag="psType.h::psMaskType" ><\/a><p>$/;"	a
+ga14	docs/html/group__Image.html	/^<a class="anchor" name="ga14" doxytag="psImageManip.h::psImageClip" ><\/a><p>$/;"	a
+ga14	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga14" doxytag="psList.h::psListSort" ><\/a><p>$/;"	a
+ga14	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga14" doxytag="psLogMsg.h::@1" ><\/a><p>$/;"	a
+ga14	docs/html/group__Metadata.html	/^<a class="anchor" name="ga14" doxytag="psMetadataIO.h::psMetadataReadHeader" ><\/a><p>$/;"	a
+ga14	docs/html/group__Stats.html	/^<a class="anchor" name="ga14" doxytag="psFunctions.h::psPolynomial2DEvalVector" ><\/a><p>$/;"	a
+ga14	docs/html/group__Time.html	/^<a class="anchor" name="ga14" doxytag="psTime.h::psTimeToTimeval" ><\/a><p>$/;"	a
+ga15	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga15" doxytag="psAstrometry.h::psCoordChipToFPA" ><\/a><p>$/;"	a
+ga15	docs/html/group__Compare.html	/^<a class="anchor" name="ga15" doxytag="psCompare.h::psCompareDescendingS64Ptr" ><\/a><p>$/;"	a
+ga15	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga15" doxytag="psCoord.h::psSpherePrecess" ><\/a><p>$/;"	a
+ga15	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga15" doxytag="psType.h::PS_TYPE_MASK" ><\/a><p>$/;"	a
+ga15	docs/html/group__Image.html	/^<a class="anchor" name="ga15" doxytag="psImageManip.h::psImageClipComplexRegion" ><\/a><p>$/;"	a
+ga15	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga15" doxytag="psList.h::@2" ><\/a><p>$/;"	a
+ga15	docs/html/group__Metadata.html	/^<a class="anchor" name="ga15" doxytag="psMetadataIO.h::psMetadataParseConfig" ><\/a><p>$/;"	a
+ga15	docs/html/group__Stats.html	/^<a class="anchor" name="ga15" doxytag="psFunctions.h::psPolynomial3DEvalVector" ><\/a><p>$/;"	a
+ga15	docs/html/group__Time.html	/^<a class="anchor" name="ga15" doxytag="psTime.h::psTimeToTM" ><\/a><p>$/;"	a
+ga16	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga16" doxytag="psAstrometry.h::psCoordFPAToTP" ><\/a><p>$/;"	a
+ga16	docs/html/group__Compare.html	/^<a class="anchor" name="ga16" doxytag="psCompare.h::psCompareDescendingU8Ptr" ><\/a><p>$/;"	a
+ga16	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga16" doxytag="psCoord.h::psProjectionType" ><\/a><p>$/;"	a
+ga16	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga16" doxytag="psType.h::PS_TYPE_MASK_DATA" ><\/a><p>$/;"	a
+ga16	docs/html/group__Image.html	/^<a class="anchor" name="ga16" doxytag="psImageManip.h::psImageClipNaN" ><\/a><p>$/;"	a
+ga16	docs/html/group__Metadata.html	/^<a class="anchor" name="ga16" doxytag="psMetadataIO.h::psMetadataParseConfigXml" ><\/a><p>$/;"	a
+ga16	docs/html/group__Stats.html	/^<a class="anchor" name="ga16" doxytag="psFunctions.h::psPolynomial4DEvalVector" ><\/a><p>$/;"	a
+ga16	docs/html/group__Time.html	/^<a class="anchor" name="ga16" doxytag="psTime.h::psTimeFromJD" ><\/a><p>$/;"	a
+ga17	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga17" doxytag="psAstrometry.h::psCoordTPToSky" ><\/a><p>$/;"	a
+ga17	docs/html/group__Compare.html	/^<a class="anchor" name="ga17" doxytag="psCompare.h::psCompareDescendingU16Ptr" ><\/a><p>$/;"	a
+ga17	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga17" doxytag="psCoord.h::psSphereOffsetMode" ><\/a><p>$/;"	a
+ga17	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga17" doxytag="psType.h::PS_TYPE_MASK_NAME" ><\/a><p>$/;"	a
+ga17	docs/html/group__Image.html	/^<a class="anchor" name="ga17" doxytag="psImageManip.h::psImageOverlaySection" ><\/a><p>$/;"	a
+ga17	docs/html/group__Metadata.html	/^<a class="anchor" name="ga17" doxytag="psMetadata.h::psMetadataType" ><\/a><p>$/;"	a
+ga17	docs/html/group__Stats.html	/^<a class="anchor" name="ga17" doxytag="psFunctions.h::psDPolynomial1DAlloc" ><\/a><p>$/;"	a
+ga17	docs/html/group__Time.html	/^<a class="anchor" name="ga17" doxytag="psTime.h::psTimeFromMJD" ><\/a><p>$/;"	a
+ga18	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga18" doxytag="psAstrometry.h::psCoordCellToFPA" ><\/a><p>$/;"	a
+ga18	docs/html/group__Compare.html	/^<a class="anchor" name="ga18" doxytag="psCompare.h::psCompareDescendingU32Ptr" ><\/a><p>$/;"	a
+ga18	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga18" doxytag="psCoord.h::psSphereOffsetUnit" ><\/a><p>$/;"	a
+ga18	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga18" doxytag="psType.h::PS_MIN_S8" ><\/a><p>$/;"	a
+ga18	docs/html/group__Image.html	/^<a class="anchor" name="ga18" doxytag="psImageManip.h::psImageRebin" ><\/a><p>$/;"	a
+ga18	docs/html/group__Stats.html	/^<a class="anchor" name="ga18" doxytag="psFunctions.h::psDPolynomial2DAlloc" ><\/a><p>$/;"	a
+ga18	docs/html/group__Time.html	/^<a class="anchor" name="ga18" doxytag="psTime.h::psTimeFromISOTime" ><\/a><p>$/;"	a
+ga19	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga19" doxytag="psAstrometry.h::psCoordCellToSky" ><\/a><p>$/;"	a
+ga19	docs/html/group__Compare.html	/^<a class="anchor" name="ga19" doxytag="psCompare.h::psCompareDescendingU64Ptr" ><\/a><p>$/;"	a
+ga19	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga19" doxytag="psType.h::PS_MIN_S16" ><\/a><p>$/;"	a
+ga19	docs/html/group__Image.html	/^<a class="anchor" name="ga19" doxytag="psImageManip.h::psImageResample" ><\/a><p>$/;"	a
+ga19	docs/html/group__Stats.html	/^<a class="anchor" name="ga19" doxytag="psFunctions.h::psDPolynomial3DAlloc" ><\/a><p>$/;"	a
+ga19	docs/html/group__Time.html	/^<a class="anchor" name="ga19" doxytag="psTime.h::psTimeFromTimeval" ><\/a><p>$/;"	a
+ga2	docs/html/group__Array.html	/^<a class="anchor" name="ga2" doxytag="psArray.h::psArrayRemove" ><\/a><p>$/;"	a
+ga2	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga2" doxytag="psAstrometry.h::psExposure" ><\/a><p>$/;"	a
+ga2	docs/html/group__BitSet.html	/^<a class="anchor" name="ga2" doxytag="psBitSet.h::psBitSetClear" ><\/a><p>$/;"	a
+ga2	docs/html/group__Compare.html	/^<a class="anchor" name="ga2" doxytag="psCompare.h::psCompareS8Ptr" ><\/a><p>$/;"	a
+ga2	docs/html/group__Configure.html	/^<a class="anchor" name="ga2" doxytag="psConfigure.h::psLibFinalize" ><\/a><p>$/;"	a
+ga2	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga2" doxytag="psCoord.h::psPlaneTransformApply" ><\/a><p>$/;"	a
+ga2	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga2" doxytag="psType.h::psU32" ><\/a><p>$/;"	a
+ga2	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga2" doxytag="psError.h::psErrorLast" ><\/a><p>$/;"	a
+ga2	docs/html/group__HashTable.html	/^<a class="anchor" name="ga2" doxytag="psHash.h::psHashAlloc" ><\/a><p>$/;"	a
+ga2	docs/html/group__Image.html	/^<a class="anchor" name="ga2" doxytag="psImage.h::psRegionAlloc" ><\/a><p>$/;"	a
+ga2	docs/html/group__ImageStats.html	/^<a class="anchor" name="ga2" doxytag="psImageStats.h::psImageFitPolynomial" ><\/a><p>$/;"	a
+ga2	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga2" doxytag="psList.h::psListIteratorAlloc" ><\/a><p>$/;"	a
+ga2	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga2" doxytag="psLogMsg.h::psLogSetLevel" ><\/a><p>$/;"	a
+ga2	docs/html/group__Math.html	/^<a class="anchor" name="ga2" doxytag="psRandom.h::psRandomUniform" ><\/a><p>$/;"	a
+ga2	docs/html/group__Matrix.html	/^<a class="anchor" name="ga2" doxytag="psMatrix.h::psMatrixInvert" ><\/a><p>$/;"	a
+ga2	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga2" doxytag="psMemory.h::psFreeFcn" ><\/a><p>$/;"	a
+ga2	docs/html/group__Metadata.html	/^<a class="anchor" name="ga2" doxytag="psMetadata.h::psMetadataItemAlloc" ><\/a><p>$/;"	a
+ga2	docs/html/group__Stats.html	/^<a class="anchor" name="ga2" doxytag="psMinimize.h::psMinimizeChi2PowellFunc" ><\/a><p>$/;"	a
+ga2	docs/html/group__Time.html	/^<a class="anchor" name="ga2" doxytag="psTime.h::psTimeFinalize" ><\/a><p>$/;"	a
+ga2	docs/html/group__Transform.html	/^<a class="anchor" name="ga2" doxytag="psImageFFT.h::psImageImaginary" ><\/a><p>$/;"	a
+ga2	docs/html/group__Vector.html	/^<a class="anchor" name="ga2" doxytag="psVector.h::psVectorRecycle" ><\/a><p>$/;"	a
+ga2	docs/html/group__memCallback.html	/^<a class="anchor" name="ga2" doxytag="psMemory.h::psMemProblemCallback" ><\/a><p>$/;"	a
+ga2	docs/html/group__memRefCount.html	/^<a class="anchor" name="ga2" doxytag="psMemory.h::psMemDecrRefCounter" ><\/a><p>$/;"	a
+ga20	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga20" doxytag="psAstrometry.h::psCoordCellToSkyQuick" ><\/a><p>$/;"	a
+ga20	docs/html/group__Compare.html	/^<a class="anchor" name="ga20" doxytag="psCompare.h::psCompareDescendingF32Ptr" ><\/a><p>$/;"	a
+ga20	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga20" doxytag="psType.h::PS_MIN_S32" ><\/a><p>$/;"	a
+ga20	docs/html/group__Image.html	/^<a class="anchor" name="ga20" doxytag="psImageManip.h::psImageRotate" ><\/a><p>$/;"	a
+ga20	docs/html/group__Stats.html	/^<a class="anchor" name="ga20" doxytag="psFunctions.h::psDPolynomial4DAlloc" ><\/a><p>$/;"	a
+ga20	docs/html/group__Time.html	/^<a class="anchor" name="ga20" doxytag="psTime.h::psTimeFromTM" ><\/a><p>$/;"	a
+ga21	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga21" doxytag="psAstrometry.h::psCoordSkyToTP" ><\/a><p>$/;"	a
+ga21	docs/html/group__Compare.html	/^<a class="anchor" name="ga21" doxytag="psCompare.h::psCompareDescendingF64Ptr" ><\/a><p>$/;"	a
+ga21	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga21" doxytag="psType.h::PS_MIN_S64" ><\/a><p>$/;"	a
+ga21	docs/html/group__Image.html	/^<a class="anchor" name="ga21" doxytag="psImageManip.h::psImageShift" ><\/a><p>$/;"	a
+ga21	docs/html/group__Stats.html	/^<a class="anchor" name="ga21" doxytag="psFunctions.h::psDPolynomial1DEval" ><\/a><p>$/;"	a
+ga21	docs/html/group__Time.html	/^<a class="anchor" name="ga21" doxytag="psTime.h::psTimeAdd" ><\/a><p>$/;"	a
+ga22	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga22" doxytag="psAstrometry.h::psCoordTPToFPA" ><\/a><p>$/;"	a
+ga22	docs/html/group__Compare.html	/^<a class="anchor" name="ga22" doxytag="psCompare.h::psCompareS8" ><\/a><p>$/;"	a
+ga22	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga22" doxytag="psType.h::PS_MIN_U8" ><\/a><p>$/;"	a
+ga22	docs/html/group__Image.html	/^<a class="anchor" name="ga22" doxytag="psImageManip.h::psImageRoll" ><\/a><p>$/;"	a
+ga22	docs/html/group__Stats.html	/^<a class="anchor" name="ga22" doxytag="psFunctions.h::psDPolynomial2DEval" ><\/a><p>$/;"	a
+ga22	docs/html/group__Time.html	/^<a class="anchor" name="ga22" doxytag="psTime.h::psTimeSubtract" ><\/a><p>$/;"	a
+ga23	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga23" doxytag="psAstrometry.h::psCoordFPAToChip" ><\/a><p>$/;"	a
+ga23	docs/html/group__Compare.html	/^<a class="anchor" name="ga23" doxytag="psCompare.h::psCompareS16" ><\/a><p>$/;"	a
+ga23	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga23" doxytag="psType.h::PS_MIN_U16" ><\/a><p>$/;"	a
+ga23	docs/html/group__Image.html	/^<a class="anchor" name="ga23" doxytag="psImage.h::p_psImagePixelInterpolateFcns" ><\/a><p>$/;"	a
+ga23	docs/html/group__Stats.html	/^<a class="anchor" name="ga23" doxytag="psFunctions.h::psDPolynomial3DEval" ><\/a><p>$/;"	a
+ga23	docs/html/group__Time.html	/^<a class="anchor" name="ga23" doxytag="psTime.h::psTimeDelta" ><\/a><p>$/;"	a
+ga24	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga24" doxytag="psAstrometry.h::psCoordChipToCell" ><\/a><p>$/;"	a
+ga24	docs/html/group__Compare.html	/^<a class="anchor" name="ga24" doxytag="psCompare.h::psCompareS32" ><\/a><p>$/;"	a
+ga24	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga24" doxytag="psType.h::PS_MIN_U32" ><\/a><p>$/;"	a
+ga24	docs/html/group__Image.html	/^<a class="anchor" name="ga24" doxytag="psImage.h::p_psImagePixelInterpolateComplexFcns" ><\/a><p>$/;"	a
+ga24	docs/html/group__Stats.html	/^<a class="anchor" name="ga24" doxytag="psFunctions.h::psDPolynomial4DEval" ><\/a><p>$/;"	a
+ga24	docs/html/group__Time.html	/^<a class="anchor" name="ga24" doxytag="psTime.h::psTimeType" ><\/a><p>$/;"	a
+ga25	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga25" doxytag="psAstrometry.h::psCoordSkyToCell" ><\/a><p>$/;"	a
+ga25	docs/html/group__Compare.html	/^<a class="anchor" name="ga25" doxytag="psCompare.h::psCompareS64" ><\/a><p>$/;"	a
+ga25	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga25" doxytag="psType.h::PS_MIN_U64" ><\/a><p>$/;"	a
+ga25	docs/html/group__Image.html	/^<a class="anchor" name="ga25" doxytag="psImage.h::psImageInterpolateMode" ><\/a><p>$/;"	a
+ga25	docs/html/group__Stats.html	/^<a class="anchor" name="ga25" doxytag="psFunctions.h::psDPolynomial1DEvalVector" ><\/a><p>$/;"	a
+ga26	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga26" doxytag="psAstrometry.h::psCoordSkyToCellQuick" ><\/a><p>$/;"	a
+ga26	docs/html/group__Compare.html	/^<a class="anchor" name="ga26" doxytag="psCompare.h::psCompareU8" ><\/a><p>$/;"	a
+ga26	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga26" doxytag="psType.h::PS_MIN_F32" ><\/a><p>$/;"	a
+ga26	docs/html/group__Image.html	/^<a class="anchor" name="ga26" doxytag="psImageExtraction.h::psImageCutDirection" ><\/a><p>$/;"	a
+ga26	docs/html/group__Stats.html	/^<a class="anchor" name="ga26" doxytag="psFunctions.h::psDPolynomial2DEvalVector" ><\/a><p>$/;"	a
+ga27	docs/html/group__Compare.html	/^<a class="anchor" name="ga27" doxytag="psCompare.h::psCompareU16" ><\/a><p>$/;"	a
+ga27	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga27" doxytag="psType.h::PS_MIN_F64" ><\/a><p>$/;"	a
+ga27	docs/html/group__Stats.html	/^<a class="anchor" name="ga27" doxytag="psFunctions.h::psDPolynomial3DEvalVector" ><\/a><p>$/;"	a
+ga28	docs/html/group__Compare.html	/^<a class="anchor" name="ga28" doxytag="psCompare.h::psCompareU32" ><\/a><p>$/;"	a
+ga28	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga28" doxytag="psType.h::PS_MIN_C32" ><\/a><p>$/;"	a
+ga28	docs/html/group__Stats.html	/^<a class="anchor" name="ga28" doxytag="psFunctions.h::psDPolynomial4DEvalVector" ><\/a><p>$/;"	a
+ga29	docs/html/group__Compare.html	/^<a class="anchor" name="ga29" doxytag="psCompare.h::psCompareU64" ><\/a><p>$/;"	a
+ga29	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga29" doxytag="psType.h::PS_MIN_C64" ><\/a><p>$/;"	a
+ga29	docs/html/group__Stats.html	/^<a class="anchor" name="ga29" doxytag="psFunctions.h::psSpline1DAlloc" ><\/a><p>$/;"	a
+ga3	docs/html/group__Array.html	/^<a class="anchor" name="ga3" doxytag="psArray.h::psArrayElementFree" ><\/a><p>$/;"	a
+ga3	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga3" doxytag="psAstrometry.h::psFixedPatternAlloc" ><\/a><p>$/;"	a
+ga3	docs/html/group__BitSet.html	/^<a class="anchor" name="ga3" doxytag="psBitSet.h::psBitSetTest" ><\/a><p>$/;"	a
+ga3	docs/html/group__Compare.html	/^<a class="anchor" name="ga3" doxytag="psCompare.h::psCompareS16Ptr" ><\/a><p>$/;"	a
+ga3	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga3" doxytag="psCoord.h::psPlaneDistortAlloc" ><\/a><p>$/;"	a
+ga3	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga3" doxytag="psType.h::psU64" ><\/a><p>$/;"	a
+ga3	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga3" doxytag="psError.h::psErrorClear" ><\/a><p>$/;"	a
+ga3	docs/html/group__HashTable.html	/^<a class="anchor" name="ga3" doxytag="psHash.h::psHashAdd" ><\/a><p>$/;"	a
+ga3	docs/html/group__Image.html	/^<a class="anchor" name="ga3" doxytag="psImage.h::psRegionFromString" ><\/a><p>$/;"	a
+ga3	docs/html/group__ImageStats.html	/^<a class="anchor" name="ga3" doxytag="psImageStats.h::psImageEvalPolynomial" ><\/a><p>$/;"	a
+ga3	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga3" doxytag="psList.h::psListIteratorSet" ><\/a><p>$/;"	a
+ga3	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga3" doxytag="psLogMsg.h::psLogSetFormat" ><\/a><p>$/;"	a
+ga3	docs/html/group__Math.html	/^<a class="anchor" name="ga3" doxytag="psRandom.h::psRandomGaussian" ><\/a><p>$/;"	a
+ga3	docs/html/group__Matrix.html	/^<a class="anchor" name="ga3" doxytag="psMatrix.h::psMatrixDeterminant" ><\/a><p>$/;"	a
+ga3	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga3" doxytag="psMemory.h::psMemBlock" ><\/a><p>$/;"	a
+ga3	docs/html/group__Metadata.html	/^<a class="anchor" name="ga3" doxytag="psMetadata.h::psMetadataItemAllocV" ><\/a><p>$/;"	a
+ga3	docs/html/group__Stats.html	/^<a class="anchor" name="ga3" doxytag="psFunctions.h::psGaussian" ><\/a><p>$/;"	a
+ga3	docs/html/group__Time.html	/^<a class="anchor" name="ga3" doxytag="psTime.h::psTimeAlloc" ><\/a><p>$/;"	a
+ga3	docs/html/group__Transform.html	/^<a class="anchor" name="ga3" doxytag="psImageFFT.h::psImageComplex" ><\/a><p>$/;"	a
+ga3	docs/html/group__Vector.html	/^<a class="anchor" name="ga3" doxytag="psVector.h::psVectorCopy" ><\/a><p>$/;"	a
+ga3	docs/html/group__memCallback.html	/^<a class="anchor" name="ga3" doxytag="psMemory.h::psMemExhaustedCallback" ><\/a><p>$/;"	a
+ga30	docs/html/group__Compare.html	/^<a class="anchor" name="ga30" doxytag="psCompare.h::psCompareF32" ><\/a><p>$/;"	a
+ga30	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga30" doxytag="psType.h::PS_MAX_S8" ><\/a><p>$/;"	a
+ga30	docs/html/group__Stats.html	/^<a class="anchor" name="ga30" doxytag="psFunctions.h::psSpline1DAllocGeneric" ><\/a><p>$/;"	a
+ga31	docs/html/group__Compare.html	/^<a class="anchor" name="ga31" doxytag="psCompare.h::psCompareF64" ><\/a><p>$/;"	a
+ga31	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga31" doxytag="psType.h::PS_MAX_S16" ><\/a><p>$/;"	a
+ga31	docs/html/group__Stats.html	/^<a class="anchor" name="ga31" doxytag="psFunctions.h::psSpline1DEval" ><\/a><p>$/;"	a
+ga32	docs/html/group__Compare.html	/^<a class="anchor" name="ga32" doxytag="psCompare.h::psCompareDescendingS8" ><\/a><p>$/;"	a
+ga32	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga32" doxytag="psType.h::PS_MAX_S32" ><\/a><p>$/;"	a
+ga32	docs/html/group__Stats.html	/^<a class="anchor" name="ga32" doxytag="psFunctions.h::psSpline1DEvalVector" ><\/a><p>$/;"	a
+ga33	docs/html/group__Compare.html	/^<a class="anchor" name="ga33" doxytag="psCompare.h::psCompareDescendingS16" ><\/a><p>$/;"	a
+ga33	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga33" doxytag="psType.h::PS_MAX_S64" ><\/a><p>$/;"	a
+ga33	docs/html/group__Stats.html	/^<a class="anchor" name="ga33" doxytag="psFunctions.h::p_psVectorBinDisect" ><\/a><p>$/;"	a
+ga34	docs/html/group__Compare.html	/^<a class="anchor" name="ga34" doxytag="psCompare.h::psCompareDescendingS32" ><\/a><p>$/;"	a
+ga34	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga34" doxytag="psType.h::PS_MAX_U8" ><\/a><p>$/;"	a
+ga34	docs/html/group__Stats.html	/^<a class="anchor" name="ga34" doxytag="psFunctions.h::p_psVectorInterpolate" ><\/a><p>$/;"	a
+ga35	docs/html/group__Compare.html	/^<a class="anchor" name="ga35" doxytag="psCompare.h::psCompareDescendingS64" ><\/a><p>$/;"	a
+ga35	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga35" doxytag="psType.h::PS_MAX_U16" ><\/a><p>$/;"	a
+ga35	docs/html/group__Stats.html	/^<a class="anchor" name="ga35" doxytag="psFunctions.h::p_psNRSpline1DEval" ><\/a><p>$/;"	a
+ga36	docs/html/group__Compare.html	/^<a class="anchor" name="ga36" doxytag="psCompare.h::psCompareDescendingU8" ><\/a><p>$/;"	a
+ga36	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga36" doxytag="psType.h::PS_MAX_U32" ><\/a><p>$/;"	a
+ga36	docs/html/group__Stats.html	/^<a class="anchor" name="ga36" doxytag="psMinimize.h::psMinimizationAlloc" ><\/a><p>$/;"	a
+ga37	docs/html/group__Compare.html	/^<a class="anchor" name="ga37" doxytag="psCompare.h::psCompareDescendingU16" ><\/a><p>$/;"	a
+ga37	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga37" doxytag="psType.h::PS_MAX_U64" ><\/a><p>$/;"	a
+ga37	docs/html/group__Stats.html	/^<a class="anchor" name="ga37" doxytag="psMinimize.h::psVectorFitPolynomial1D" ><\/a><p>$/;"	a
+ga38	docs/html/group__Compare.html	/^<a class="anchor" name="ga38" doxytag="psCompare.h::psCompareDescendingU32" ><\/a><p>$/;"	a
+ga38	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga38" doxytag="psType.h::PS_MAX_F32" ><\/a><p>$/;"	a
+ga38	docs/html/group__Stats.html	/^<a class="anchor" name="ga38" doxytag="psMinimize.h::psVectorFitSpline1D" ><\/a><p>$/;"	a
+ga39	docs/html/group__Compare.html	/^<a class="anchor" name="ga39" doxytag="psCompare.h::psCompareDescendingU64" ><\/a><p>$/;"	a
+ga39	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga39" doxytag="psType.h::PS_MAX_F64" ><\/a><p>$/;"	a
+ga39	docs/html/group__Stats.html	/^<a class="anchor" name="ga39" doxytag="psMinimize.h::psMinimizeLMChi2" ><\/a><p>$/;"	a
+ga4	docs/html/group__Array.html	/^<a class="anchor" name="ga4" doxytag="psArray.h::psArraySort" ><\/a><p>$/;"	a
+ga4	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga4" doxytag="psAstrometry.h::psExposureAlloc" ><\/a><p>$/;"	a
+ga4	docs/html/group__BitSet.html	/^<a class="anchor" name="ga4" doxytag="psBitSet.h::psBitSetOp" ><\/a><p>$/;"	a
+ga4	docs/html/group__Compare.html	/^<a class="anchor" name="ga4" doxytag="psCompare.h::psCompareS32Ptr" ><\/a><p>$/;"	a
+ga4	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga4" doxytag="psCoord.h::psPlaneDistortApply" ><\/a><p>$/;"	a
+ga4	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga4" doxytag="psType.h::psS8" ><\/a><p>$/;"	a
+ga4	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga4" doxytag="psError.h::psErrorStackPrint" ><\/a><p>$/;"	a
+ga4	docs/html/group__HashTable.html	/^<a class="anchor" name="ga4" doxytag="psHash.h::psHashLookup" ><\/a><p>$/;"	a
+ga4	docs/html/group__Image.html	/^<a class="anchor" name="ga4" doxytag="psImage.h::psImageRecycle" ><\/a><p>$/;"	a
+ga4	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga4" doxytag="psList.h::psListAdd" ><\/a><p>$/;"	a
+ga4	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga4" doxytag="psLogMsg.h::psLogMsg" ><\/a><p>$/;"	a
+ga4	docs/html/group__Math.html	/^<a class="anchor" name="ga4" doxytag="psRandom.h::psRandomPoisson" ><\/a><p>$/;"	a
+ga4	docs/html/group__Matrix.html	/^<a class="anchor" name="ga4" doxytag="psMatrix.h::psMatrixMultiply" ><\/a><p>$/;"	a
+ga4	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga4" doxytag="psMemory.h::psAlloc" ><\/a><p>$/;"	a
+ga4	docs/html/group__Metadata.html	/^<a class="anchor" name="ga4" doxytag="psMetadata.h::psMetadataAlloc" ><\/a><p>$/;"	a
+ga4	docs/html/group__Stats.html	/^<a class="anchor" name="ga4" doxytag="psFunctions.h::p_psGaussianDev" ><\/a><p>$/;"	a
+ga4	docs/html/group__Time.html	/^<a class="anchor" name="ga4" doxytag="psTime.h::psTimeGetTime" ><\/a><p>$/;"	a
+ga4	docs/html/group__Transform.html	/^<a class="anchor" name="ga4" doxytag="psImageFFT.h::psImageConjugate" ><\/a><p>$/;"	a
+ga4	docs/html/group__Vector.html	/^<a class="anchor" name="ga4" doxytag="psVector.h::psVectorSort" ><\/a><p>$/;"	a
+ga4	docs/html/group__memCallback.html	/^<a class="anchor" name="ga4" doxytag="psMemory.h::psMemProblemCallbackSet" ><\/a><p>$/;"	a
+ga40	docs/html/group__Compare.html	/^<a class="anchor" name="ga40" doxytag="psCompare.h::psCompareDescendingF32" ><\/a><p>$/;"	a
+ga40	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga40" doxytag="psType.h::PS_MAX_C32" ><\/a><p>$/;"	a
+ga40	docs/html/group__Stats.html	/^<a class="anchor" name="ga40" doxytag="psMinimize.h::psMinimizePowell" ><\/a><p>$/;"	a
+ga41	docs/html/group__Compare.html	/^<a class="anchor" name="ga41" doxytag="psCompare.h::psCompareDescendingF64" ><\/a><p>$/;"	a
+ga41	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga41" doxytag="psType.h::PS_MAX_C64" ><\/a><p>$/;"	a
+ga41	docs/html/group__Stats.html	/^<a class="anchor" name="ga41" doxytag="psMinimize.h::psMinimizeLMChi2Gauss1D" ><\/a><p>$/;"	a
+ga42	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga42" doxytag="psType.h::PS_TYPE_BOOL_NAME" ><\/a><p>$/;"	a
+ga42	docs/html/group__Stats.html	/^<a class="anchor" name="ga42" doxytag="psMinimize.h::psMinimizePowellChi2Gauss1D" ><\/a><p>$/;"	a
+ga43	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga43" doxytag="psType.h::PS_TYPE_S8_NAME" ><\/a><p>$/;"	a
+ga43	docs/html/group__Stats.html	/^<a class="anchor" name="ga43" doxytag="psMinimize.h::psMinimizeChi2Powell" ><\/a><p>$/;"	a
+ga44	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga44" doxytag="psType.h::PS_TYPE_S16_NAME" ><\/a><p>$/;"	a
+ga44	docs/html/group__Stats.html	/^<a class="anchor" name="ga44" doxytag="psStats.h::psVectorStats" ><\/a><p>$/;"	a
+ga45	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga45" doxytag="psType.h::PS_TYPE_S32_NAME" ><\/a><p>$/;"	a
+ga45	docs/html/group__Stats.html	/^<a class="anchor" name="ga45" doxytag="psStats.h::psStatsAlloc" ><\/a><p>$/;"	a
+ga46	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga46" doxytag="psType.h::PS_TYPE_S64_NAME" ><\/a><p>$/;"	a
+ga46	docs/html/group__Stats.html	/^<a class="anchor" name="ga46" doxytag="psStats.h::psHistogramAlloc" ><\/a><p>$/;"	a
+ga47	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga47" doxytag="psType.h::PS_TYPE_U8_NAME" ><\/a><p>$/;"	a
+ga47	docs/html/group__Stats.html	/^<a class="anchor" name="ga47" doxytag="psStats.h::psHistogramAllocGeneric" ><\/a><p>$/;"	a
+ga48	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga48" doxytag="psType.h::PS_TYPE_U16_NAME" ><\/a><p>$/;"	a
+ga48	docs/html/group__Stats.html	/^<a class="anchor" name="ga48" doxytag="psStats.h::psVectorHistogram" ><\/a><p>$/;"	a
+ga49	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga49" doxytag="psType.h::PS_TYPE_U32_NAME" ><\/a><p>$/;"	a
+ga49	docs/html/group__Stats.html	/^<a class="anchor" name="ga49" doxytag="psStats.h::p_psGetStatValue" ><\/a><p>$/;"	a
+ga5	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga5" doxytag="psAstrometry.h::psObservatoryAlloc" ><\/a><p>$/;"	a
+ga5	docs/html/group__BitSet.html	/^<a class="anchor" name="ga5" doxytag="psBitSet.h::psBitSetNot" ><\/a><p>$/;"	a
+ga5	docs/html/group__Compare.html	/^<a class="anchor" name="ga5" doxytag="psCompare.h::psCompareS64Ptr" ><\/a><p>$/;"	a
+ga5	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga5" doxytag="psCoord.h::psSphereTransformAlloc" ><\/a><p>$/;"	a
+ga5	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga5" doxytag="psType.h::psS16" ><\/a><p>$/;"	a
+ga5	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga5" doxytag="psError.h::psErrorStackPrintV" ><\/a><p>$/;"	a
+ga5	docs/html/group__HashTable.html	/^<a class="anchor" name="ga5" doxytag="psHash.h::psHashRemove" ><\/a><p>$/;"	a
+ga5	docs/html/group__Image.html	/^<a class="anchor" name="ga5" doxytag="psImage.h::psImageCopy" ><\/a><p>$/;"	a
+ga5	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga5" doxytag="psList.h::psListAddAfter" ><\/a><p>$/;"	a
+ga5	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga5" doxytag="psLogMsg.h::psLogMsgV" ><\/a><p>$/;"	a
+ga5	docs/html/group__Math.html	/^<a class="anchor" name="ga5" doxytag="psRandom.h::psRandomType" ><\/a><p>$/;"	a
+ga5	docs/html/group__Matrix.html	/^<a class="anchor" name="ga5" doxytag="psMatrix.h::psMatrixTranspose" ><\/a><p>$/;"	a
+ga5	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga5" doxytag="psMemory.h::p_psMemSetDeallocator" ><\/a><p>$/;"	a
+ga5	docs/html/group__Metadata.html	/^<a class="anchor" name="ga5" doxytag="psMetadata.h::psMetadataAddItem" ><\/a><p>$/;"	a
+ga5	docs/html/group__Stats.html	/^<a class="anchor" name="ga5" doxytag="psFunctions.h::psPolynomial1DAlloc" ><\/a><p>$/;"	a
+ga5	docs/html/group__Time.html	/^<a class="anchor" name="ga5" doxytag="psTime.h::psTimeConvert" ><\/a><p>$/;"	a
+ga5	docs/html/group__Transform.html	/^<a class="anchor" name="ga5" doxytag="psImageFFT.h::psImagePowerSpectrum" ><\/a><p>$/;"	a
+ga5	docs/html/group__Vector.html	/^<a class="anchor" name="ga5" doxytag="psVector.h::psVectorSortIndex" ><\/a><p>$/;"	a
+ga5	docs/html/group__memCallback.html	/^<a class="anchor" name="ga5" doxytag="psMemory.h::psMemExhaustedCallbackSet" ><\/a><p>$/;"	a
+ga50	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga50" doxytag="psType.h::PS_TYPE_U64_NAME" ><\/a><p>$/;"	a
+ga50	docs/html/group__Stats.html	/^<a class="anchor" name="ga50" doxytag="psStats.h::p_psNormalizeVectorRangeU8" ><\/a><p>$/;"	a
+ga51	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga51" doxytag="psType.h::PS_TYPE_F32_NAME" ><\/a><p>$/;"	a
+ga51	docs/html/group__Stats.html	/^<a class="anchor" name="ga51" doxytag="psStats.h::p_psNormalizeVectorRangeU16" ><\/a><p>$/;"	a
+ga52	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga52" doxytag="psType.h::PS_TYPE_F64_NAME" ><\/a><p>$/;"	a
+ga52	docs/html/group__Stats.html	/^<a class="anchor" name="ga52" doxytag="psStats.h::p_psNormalizeVectorRangeU32" ><\/a><p>$/;"	a
+ga53	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga53" doxytag="psType.h::PS_TYPE_C32_NAME" ><\/a><p>$/;"	a
+ga53	docs/html/group__Stats.html	/^<a class="anchor" name="ga53" doxytag="psStats.h::p_psNormalizeVectorRangeU64" ><\/a><p>$/;"	a
+ga54	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga54" doxytag="psType.h::PS_TYPE_C64_NAME" ><\/a><p>$/;"	a
+ga54	docs/html/group__Stats.html	/^<a class="anchor" name="ga54" doxytag="psStats.h::p_psNormalizeVectorRangeS8" ><\/a><p>$/;"	a
+ga55	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga55" doxytag="psType.h::PS_TYPE_PTR_NAME" ><\/a><p>$/;"	a
+ga55	docs/html/group__Stats.html	/^<a class="anchor" name="ga55" doxytag="psStats.h::p_psNormalizeVectorRangeS16" ><\/a><p>$/;"	a
+ga56	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga56" doxytag="psType.h::PS_TYPE_NAME" ><\/a><p>$/;"	a
+ga56	docs/html/group__Stats.html	/^<a class="anchor" name="ga56" doxytag="psStats.h::p_psNormalizeVectorRangeS32" ><\/a><p>$/;"	a
+ga57	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga57" doxytag="psType.h::PS_BADPIXEL_BITMASK" ><\/a><p>$/;"	a
+ga57	docs/html/group__Stats.html	/^<a class="anchor" name="ga57" doxytag="psStats.h::p_psNormalizeVectorRangeS64" ><\/a><p>$/;"	a
+ga58	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga58" doxytag="psType.h::PS_GET_BADPIXEL" ><\/a><p>$/;"	a
+ga58	docs/html/group__Stats.html	/^<a class="anchor" name="ga58" doxytag="psStats.h::p_psNormalizeVectorRangeF32" ><\/a><p>$/;"	a
+ga59	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga59" doxytag="psType.h::PS_IS_BADPIXEL" ><\/a><p>$/;"	a
+ga59	docs/html/group__Stats.html	/^<a class="anchor" name="ga59" doxytag="psStats.h::p_psNormalizeVectorRangeF64" ><\/a><p>$/;"	a
+ga6	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga6" doxytag="psAstrometry.h::psFPAAlloc" ><\/a><p>$/;"	a
+ga6	docs/html/group__BitSet.html	/^<a class="anchor" name="ga6" doxytag="psBitSet.h::psBitSetToString" ><\/a><p>$/;"	a
+ga6	docs/html/group__Compare.html	/^<a class="anchor" name="ga6" doxytag="psCompare.h::psCompareU8Ptr" ><\/a><p>$/;"	a
+ga6	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga6" doxytag="psCoord.h::psSphereTransformApply" ><\/a><p>$/;"	a
+ga6	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga6" doxytag="psType.h::psS32" ><\/a><p>$/;"	a
+ga6	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga6" doxytag="psError.h::p_psError" ><\/a><p>$/;"	a
+ga6	docs/html/group__HashTable.html	/^<a class="anchor" name="ga6" doxytag="psHash.h::psHashKeyList" ><\/a><p>$/;"	a
+ga6	docs/html/group__Image.html	/^<a class="anchor" name="ga6" doxytag="psImage.h::psImageFreeChildren" ><\/a><p>$/;"	a
+ga6	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga6" doxytag="psList.h::psListAddBefore" ><\/a><p>$/;"	a
+ga6	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga6" doxytag="psLogMsg.h::psWarning" ><\/a><p>$/;"	a
+ga6	docs/html/group__Matrix.html	/^<a class="anchor" name="ga6" doxytag="psMatrix.h::psMatrixEigenvectors" ><\/a><p>$/;"	a
+ga6	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga6" doxytag="psMemory.h::p_psMemGetDeallocator" ><\/a><p>$/;"	a
+ga6	docs/html/group__Metadata.html	/^<a class="anchor" name="ga6" doxytag="psMetadata.h::psMetadataAdd" ><\/a><p>$/;"	a
+ga6	docs/html/group__Stats.html	/^<a class="anchor" name="ga6" doxytag="psFunctions.h::psPolynomial2DAlloc" ><\/a><p>$/;"	a
+ga6	docs/html/group__Time.html	/^<a class="anchor" name="ga6" doxytag="psTime.h::psTimeToLST" ><\/a><p>$/;"	a
+ga6	docs/html/group__Transform.html	/^<a class="anchor" name="ga6" doxytag="psVectorFFT.h::psVectorFFT" ><\/a><p>$/;"	a
+ga6	docs/html/group__memCallback.html	/^<a class="anchor" name="ga6" doxytag="psMemory.h::psMemAllocateCallbackSet" ><\/a><p>$/;"	a
+ga60	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga60" doxytag="psType.h::PS_SET_BADPIXEL" ><\/a><p>$/;"	a
+ga60	docs/html/group__Stats.html	/^<a class="anchor" name="ga60" doxytag="psFunctions.h::psPolynomialType" ><\/a><p>$/;"	a
+ga61	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga61" doxytag="psType.h::PS_IS_PSELEMTYPE_INT" ><\/a><p>$/;"	a
+ga61	docs/html/group__Stats.html	/^<a class="anchor" name="ga61" doxytag="psStats.h::psStatsOptions" ><\/a><p>$/;"	a
+ga62	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga62" doxytag="psType.h::PS_IS_PSELEMTYPE_UNSIGNED" ><\/a><p>$/;"	a
+ga63	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga63" doxytag="psType.h::PS_IS_PSELEMTYPE_REAL" ><\/a><p>$/;"	a
+ga64	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga64" doxytag="psType.h::PS_IS_PSELEMTYPE_COMPLEX" ><\/a><p>$/;"	a
+ga65	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga65" doxytag="psType.h::PS_IS_PSELEMTYPE_BOOL" ><\/a><p>$/;"	a
+ga66	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga66" doxytag="psType.h::PSELEMTYPE_SIZEOF" ><\/a><p>$/;"	a
+ga67	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga67" doxytag="psType.h::psElemType" ><\/a><p>$/;"	a
+ga68	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga68" doxytag="psType.h::psDimen" ><\/a><p>$/;"	a
+ga7	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga7" doxytag="psAstrometry.h::psChipAlloc" ><\/a><p>$/;"	a
+ga7	docs/html/group__Compare.html	/^<a class="anchor" name="ga7" doxytag="psCompare.h::psCompareU16Ptr" ><\/a><p>$/;"	a
+ga7	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga7" doxytag="psCoord.h::psSphereTransformICRSToEcliptic" ><\/a><p>$/;"	a
+ga7	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga7" doxytag="psType.h::psS64" ><\/a><p>$/;"	a
+ga7	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga7" doxytag="psError.h::psErrAlloc" ><\/a><p>$/;"	a
+ga7	docs/html/group__Image.html	/^<a class="anchor" name="ga7" doxytag="psImage.h::psImagePixelInterpolate" ><\/a><p>$/;"	a
+ga7	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga7" doxytag="psList.h::psListRemove" ><\/a><p>$/;"	a
+ga7	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga7" doxytag="psTrace.h::psTraceSetLevel" ><\/a><p>$/;"	a
+ga7	docs/html/group__Matrix.html	/^<a class="anchor" name="ga7" doxytag="psMatrix.h::psMatrixToVector" ><\/a><p>$/;"	a
+ga7	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga7" doxytag="psMemory.h::p_psMemSetPersistent" ><\/a><p>$/;"	a
+ga7	docs/html/group__Metadata.html	/^<a class="anchor" name="ga7" doxytag="psMetadata.h::psMetadataRemove" ><\/a><p>$/;"	a
+ga7	docs/html/group__Stats.html	/^<a class="anchor" name="ga7" doxytag="psFunctions.h::psPolynomial3DAlloc" ><\/a><p>$/;"	a
+ga7	docs/html/group__Time.html	/^<a class="anchor" name="ga7" doxytag="psTime.h::psTimeGetUT1Delta" ><\/a><p>$/;"	a
+ga7	docs/html/group__Transform.html	/^<a class="anchor" name="ga7" doxytag="psVectorFFT.h::psVectorReal" ><\/a><p>$/;"	a
+ga7	docs/html/group__memCallback.html	/^<a class="anchor" name="ga7" doxytag="psMemory.h::psMemFreeCallbackSet" ><\/a><p>$/;"	a
+ga8	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga8" doxytag="psAstrometry.h::psCellAlloc" ><\/a><p>$/;"	a
+ga8	docs/html/group__Compare.html	/^<a class="anchor" name="ga8" doxytag="psCompare.h::psCompareU32Ptr" ><\/a><p>$/;"	a
+ga8	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga8" doxytag="psCoord.h::psSphereTransformEclipticToICRS" ><\/a><p>$/;"	a
+ga8	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga8" doxytag="psType.h::psF32" ><\/a><p>$/;"	a
+ga8	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga8" doxytag="psErrorCodes.h::psErrorDescriptionAlloc" ><\/a><p>$/;"	a
+ga8	docs/html/group__Image.html	/^<a class="anchor" name="ga8" doxytag="psImageExtraction.h::psImageSubset" ><\/a><p>$/;"	a
+ga8	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga8" doxytag="psList.h::psListRemoveData" ><\/a><p>$/;"	a
+ga8	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga8" doxytag="psTrace.h::psTraceGetLevel" ><\/a><p>$/;"	a
+ga8	docs/html/group__Matrix.html	/^<a class="anchor" name="ga8" doxytag="psMatrix.h::psVectorToMatrix" ><\/a><p>$/;"	a
+ga8	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga8" doxytag="psMemory.h::p_psMemGetPersistent" ><\/a><p>$/;"	a
+ga8	docs/html/group__Metadata.html	/^<a class="anchor" name="ga8" doxytag="psMetadata.h::psMetadataLookup" ><\/a><p>$/;"	a
+ga8	docs/html/group__Stats.html	/^<a class="anchor" name="ga8" doxytag="psFunctions.h::psPolynomial4DAlloc" ><\/a><p>$/;"	a
+ga8	docs/html/group__Time.html	/^<a class="anchor" name="ga8" doxytag="psTime.h::psTimeGetTAIDelta" ><\/a><p>$/;"	a
+ga8	docs/html/group__Transform.html	/^<a class="anchor" name="ga8" doxytag="psVectorFFT.h::psVectorImaginary" ><\/a><p>$/;"	a
+ga8	docs/html/group__memCallback.html	/^<a class="anchor" name="ga8" doxytag="psMemory.h::psMemGetId" ><\/a><p>$/;"	a
+ga9	docs/html/group__AstroImage.html	/^<a class="anchor" name="ga9" doxytag="psAstrometry.h::psReadoutAlloc" ><\/a><p>$/;"	a
+ga9	docs/html/group__Compare.html	/^<a class="anchor" name="ga9" doxytag="psCompare.h::psCompareU64Ptr" ><\/a><p>$/;"	a
+ga9	docs/html/group__CoordinateTransform.html	/^<a class="anchor" name="ga9" doxytag="psCoord.h::psSphereTransformICRSToGalatic" ><\/a><p>$/;"	a
+ga9	docs/html/group__DataContainer.html	/^<a class="anchor" name="ga9" doxytag="psType.h::psF64" ><\/a><p>$/;"	a
+ga9	docs/html/group__ErrorHandling.html	/^<a class="anchor" name="ga9" doxytag="psErrorCodes.h::psErrorCodeString" ><\/a><p>$/;"	a
+ga9	docs/html/group__Image.html	/^<a class="anchor" name="ga9" doxytag="psImageExtraction.h::psImageSubsection" ><\/a><p>$/;"	a
+ga9	docs/html/group__LinkedList.html	/^<a class="anchor" name="ga9" doxytag="psList.h::psListGet" ><\/a><p>$/;"	a
+ga9	docs/html/group__LogTrace.html	/^<a class="anchor" name="ga9" doxytag="psTrace.h::psTraceReset" ><\/a><p>$/;"	a
+ga9	docs/html/group__MemoryManagement.html	/^<a class="anchor" name="ga9" doxytag="psMemory.h::psRealloc" ><\/a><p>$/;"	a
+ga9	docs/html/group__Metadata.html	/^<a class="anchor" name="ga9" doxytag="psMetadata.h::psMetadataLookupF64" ><\/a><p>$/;"	a
+ga9	docs/html/group__Stats.html	/^<a class="anchor" name="ga9" doxytag="psFunctions.h::psPolynomial1DEval" ><\/a><p>$/;"	a
+ga9	docs/html/group__Time.html	/^<a class="anchor" name="ga9" doxytag="psTime.h::psTimeGetPoleCoords" ><\/a><p>$/;"	a
+ga9	docs/html/group__Transform.html	/^<a class="anchor" name="ga9" doxytag="psVectorFFT.h::psVectorComplex" ><\/a><p>$/;"	a
+ga9	docs/html/group__memCallback.html	/^<a class="anchor" name="ga9" doxytag="psMemory.h::psMemAllocateCallbackSetID" ><\/a><p>$/;"	a
+genGaussianVector	test/dataManip/tst_psMinimize07.c	/^psVector *genGaussianVector(int n, float mean, float stdev)$/;"	f
+genSystem	test/astronomy/tst_psAstrometry01.c	/^psFPA *genSystem()$/;"	f
+getErrorDescription	src/sysUtils/psErrorCodes.c	/^static const psErrorDescription* getErrorDescription(psErrorCode code)$/;"	f	file:
+getErrorDescription	src/sysUtils/psErrorCodes.c	/^static const psErrorDescription* getErrorDescription(psErrorCode code);$/;"	p	file:
+getToken	src/astronomy/psMetadataIO.c	/^char* getToken(char **inString, char *delimiter, psS32 *status)$/;"	f
+getToken	src/astronomy/psTime.c	/^static char* getToken(char **inString, char *delimiter, psParseErrorType *status)$/;"	f	file:
+getToken	src/astronomy/psTime.c	/^static char* getToken(char **inString, char *delimiter, psParseErrorType *status);$/;"	p	file:
+getToken	src/fileUtils/psLookupTable.c	/^static char* getToken(char **inString, char *delimiter, psParseErrorType *status)$/;"	f	file:
+getToken	src/fileUtils/psLookupTable.c	/^static char* getToken(char **inString, char *delimiter, psParseErrorType *status);$/;"	p	file:
+gga12a0	docs/html/group__Transform.html	/^<tr><td valign=top><em><a class="anchor" name="gga12a0" doxytag="PS_FFT_FORWARD" ><\/a>PS_FFT_FORWARD<\/em>&nbsp;<\/td><td>$/;"	a
+gga12a1	docs/html/group__Transform.html	/^<tr><td valign=top><em><a class="anchor" name="gga12a1" doxytag="PS_FFT_REVERSE" ><\/a>PS_FFT_REVERSE<\/em>&nbsp;<\/td><td>$/;"	a
+gga12a2	docs/html/group__Transform.html	/^<tr><td valign=top><em><a class="anchor" name="gga12a2" doxytag="PS_FFT_REAL_RESULT" ><\/a>PS_FFT_REAL_RESULT<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a0	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a0" doxytag="PS_ERR_NONE" ><\/a>PS_ERR_NONE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a1	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a1" doxytag="PS_ERR_BASE" ><\/a>PS_ERR_BASE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a1	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a1" doxytag="PS_LOG_ABORT" ><\/a>PS_LOG_ABORT<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a10	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a10" doxytag="PS_ERR_BAD_PARAMETER_SIZE" ><\/a>PS_ERR_BAD_PARAMETER_SIZE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a11	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a11" doxytag="PS_ERR_UNEXPECTED_NULL" ><\/a>PS_ERR_UNEXPECTED_NULL<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a12	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a12" doxytag="PS_ERR_OS_CALL_FAILED" ><\/a>PS_ERR_OS_CALL_FAILED<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a13	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a13" doxytag="PS_ERR_N_ERR_CLASSES" ><\/a>PS_ERR_N_ERR_CLASSES<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a2	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a2" doxytag="PS_ERR_UNKNOWN" ><\/a>PS_ERR_UNKNOWN<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a2	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a2" doxytag="PS_LOG_ERROR" ><\/a>PS_LOG_ERROR<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a3	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a3" doxytag="PS_ERR_IO" ><\/a>PS_ERR_IO<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a3	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a3" doxytag="PS_LOG_WARN" ><\/a>PS_LOG_WARN<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a4	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a4" doxytag="PS_ERR_LOCATION_INVALID" ><\/a>PS_ERR_LOCATION_INVALID<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a4	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a4" doxytag="PS_LOG_INFO" ><\/a>PS_LOG_INFO<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a5	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a5" doxytag="PS_ERR_MEMORY_CORRUPTION" ><\/a>PS_ERR_MEMORY_CORRUPTION<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a6	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a6" doxytag="PS_ERR_MEMORY_DEREF_USAGE" ><\/a>PS_ERR_MEMORY_DEREF_USAGE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a7	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a7" doxytag="PS_ERR_BAD_PARAMETER_VALUE" ><\/a>PS_ERR_BAD_PARAMETER_VALUE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a8	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a8" doxytag="PS_ERR_BAD_PARAMETER_TYPE" ><\/a>PS_ERR_BAD_PARAMETER_TYPE<\/em>&nbsp;<\/td><td>$/;"	a
+gga13a9	docs/html/group__ErrorHandling.html	/^<tr><td valign=top><em><a class="anchor" name="gga13a9" doxytag="PS_ERR_BAD_PARAMETER_NULL" ><\/a>PS_ERR_BAD_PARAMETER_NULL<\/em>&nbsp;<\/td><td>$/;"	a
+gga14a5	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga14a5" doxytag="PS_LOG_NONE" ><\/a>PS_LOG_NONE<\/em>&nbsp;<\/td><td>$/;"	a
+gga14a6	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga14a6" doxytag="PS_LOG_TO_STDERR" ><\/a>PS_LOG_TO_STDERR<\/em>&nbsp;<\/td><td>$/;"	a
+gga14a7	docs/html/group__LogTrace.html	/^<tr><td valign=top><em><a class="anchor" name="gga14a7" doxytag="PS_LOG_TO_STDOUT" ><\/a>PS_LOG_TO_STDOUT<\/em>&nbsp;<\/td><td>$/;"	a
+gga15a2	docs/html/group__LinkedList.html	/^<tr><td valign=top><em><a class="anchor" name="gga15a2" doxytag="PS_LIST_HEAD" ><\/a>PS_LIST_HEAD<\/em>&nbsp;<\/td><td>$/;"	a
+gga15a3	docs/html/group__LinkedList.html	/^<tr><td valign=top><em><a class="anchor" name="gga15a3" doxytag="PS_LIST_TAIL" ><\/a>PS_LIST_TAIL<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a1	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a1" doxytag="PS_PROJ_TAN" ><\/a>PS_PROJ_TAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a2	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a2" doxytag="PS_PROJ_SIN" ><\/a>PS_PROJ_SIN<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a3	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a3" doxytag="PS_PROJ_AIT" ><\/a>PS_PROJ_AIT<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a4	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a4" doxytag="PS_PROJ_PAR" ><\/a>PS_PROJ_PAR<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a5	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a5" doxytag="PS_PROJ_GLS" ><\/a>PS_PROJ_GLS<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a6	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a6" doxytag="PS_PROJ_CAR" ><\/a>PS_PROJ_CAR<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a7	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a7" doxytag="PS_PROJ_MER" ><\/a>PS_PROJ_MER<\/em>&nbsp;<\/td><td>$/;"	a
+gga16a8	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga16a8" doxytag="PS_PROJ_NTYPE" ><\/a>PS_PROJ_NTYPE<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a10	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a10" doxytag="PS_LINEAR" ><\/a>PS_LINEAR<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a10	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a10" doxytag="PS_META_PNG" ><\/a>PS_META_PNG<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a11	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a11" doxytag="PS_META_ASTROM" ><\/a>PS_META_ASTROM<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a12	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a12" doxytag="PS_META_UNKNOWN" ><\/a>PS_META_UNKNOWN<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a13	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a13" doxytag="PS_META_NTYPE" ><\/a>PS_META_NTYPE<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a2	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a2" doxytag="PS_META_PRIMITIVE" ><\/a>PS_META_PRIMITIVE<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a3	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a3" doxytag="PS_META_LIST" ><\/a>PS_META_LIST<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a4	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a4" doxytag="PS_META_STR" ><\/a>PS_META_STR<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a5	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a5" doxytag="PS_META_VEC" ><\/a>PS_META_VEC<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a6	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a6" doxytag="PS_META_IMG" ><\/a>PS_META_IMG<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a7	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a7" doxytag="PS_META_HASH" ><\/a>PS_META_HASH<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a8	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a8" doxytag="PS_META_LOOKUPTABLE" ><\/a>PS_META_LOOKUPTABLE<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a9	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a9" doxytag="PS_SPHERICAL" ><\/a>PS_SPHERICAL<\/em>&nbsp;<\/td><td>$/;"	a
+gga17a9	docs/html/group__Metadata.html	/^<tr><td valign=top><em><a class="anchor" name="gga17a9" doxytag="PS_META_JPEG" ><\/a>PS_META_JPEG<\/em>&nbsp;<\/td><td>$/;"	a
+gga18a11	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga18a11" doxytag="PS_ARCSEC" ><\/a>PS_ARCSEC<\/em>&nbsp;<\/td><td>$/;"	a
+gga18a12	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga18a12" doxytag="PS_ARCMIN" ><\/a>PS_ARCMIN<\/em>&nbsp;<\/td><td>$/;"	a
+gga18a13	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga18a13" doxytag="PS_DEGREE" ><\/a>PS_DEGREE<\/em>&nbsp;<\/td><td>$/;"	a
+gga18a14	docs/html/group__CoordinateTransform.html	/^<tr><td valign=top><em><a class="anchor" name="gga18a14" doxytag="PS_RADIAN" ><\/a>PS_RADIAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga24a1	docs/html/group__Time.html	/^<tr><td valign=top><em><a class="anchor" name="gga24a1" doxytag="PS_TIME_TAI" ><\/a>PS_TIME_TAI<\/em>&nbsp;<\/td><td>$/;"	a
+gga24a2	docs/html/group__Time.html	/^<tr><td valign=top><em><a class="anchor" name="gga24a2" doxytag="PS_TIME_UTC" ><\/a>PS_TIME_UTC<\/em>&nbsp;<\/td><td>$/;"	a
+gga25a3	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga25a3" doxytag="PS_INTERPOLATE_FLAT" ><\/a>PS_INTERPOLATE_FLAT<\/em>&nbsp;<\/td><td>$/;"	a
+gga25a4	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga25a4" doxytag="PS_INTERPOLATE_BILINEAR" ><\/a>PS_INTERPOLATE_BILINEAR<\/em>&nbsp;<\/td><td>$/;"	a
+gga25a5	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga25a5" doxytag="PS_INTERPOLATE_BICUBIC" ><\/a>PS_INTERPOLATE_BICUBIC<\/em>&nbsp;<\/td><td>$/;"	a
+gga25a6	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga25a6" doxytag="PS_INTERPOLATE_SINC" ><\/a>PS_INTERPOLATE_SINC<\/em>&nbsp;<\/td><td>$/;"	a
+gga25a7	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga25a7" doxytag="PS_INTERPOLATE_NUM_MODES" ><\/a>PS_INTERPOLATE_NUM_MODES<\/em>&nbsp;<\/td><td>$/;"	a
+gga26a0	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga26a0" doxytag="PS_CUT_X_POS" ><\/a>PS_CUT_X_POS<\/em>&nbsp;<\/td><td>$/;"	a
+gga26a1	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga26a1" doxytag="PS_CUT_X_NEG" ><\/a>PS_CUT_X_NEG<\/em>&nbsp;<\/td><td>$/;"	a
+gga26a2	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga26a2" doxytag="PS_CUT_Y_POS" ><\/a>PS_CUT_Y_POS<\/em>&nbsp;<\/td><td>$/;"	a
+gga26a3	docs/html/group__Image.html	/^<tr><td valign=top><em><a class="anchor" name="gga26a3" doxytag="PS_CUT_Y_NEG" ><\/a>PS_CUT_Y_NEG<\/em>&nbsp;<\/td><td>$/;"	a
+gga5a1	docs/html/group__Math.html	/^<tr><td valign=top><em><a class="anchor" name="gga5a1" doxytag="PS_RANDOM_TAUS" ><\/a>PS_RANDOM_TAUS<\/em>&nbsp;<\/td><td>$/;"	a
+gga60a1	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga60a1" doxytag="PS_POLYNOMIAL_ORD" ><\/a>PS_POLYNOMIAL_ORD<\/em>&nbsp;<\/td><td>$/;"	a
+gga60a2	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga60a2" doxytag="PS_POLYNOMIAL_CHEB" ><\/a>PS_POLYNOMIAL_CHEB<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a1	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a1" doxytag="PS_STAT_SAMPLE_MEAN" ><\/a>PS_STAT_SAMPLE_MEAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a10	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a10" doxytag="PS_STAT_CLIPPED_MEAN" ><\/a>PS_STAT_CLIPPED_MEAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a11	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a11" doxytag="PS_STAT_CLIPPED_STDEV" ><\/a>PS_STAT_CLIPPED_STDEV<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a12	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a12" doxytag="PS_STAT_MAX" ><\/a>PS_STAT_MAX<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a13	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a13" doxytag="PS_STAT_MIN" ><\/a>PS_STAT_MIN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a14	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a14" doxytag="PS_STAT_USE_RANGE" ><\/a>PS_STAT_USE_RANGE<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a15	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a15" doxytag="PS_STAT_USE_BINSIZE" ><\/a>PS_STAT_USE_BINSIZE<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a16	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a16" doxytag="PS_STAT_ROBUST_FOR_SAMPLE" ><\/a>PS_STAT_ROBUST_FOR_SAMPLE<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a2	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a2" doxytag="PS_STAT_SAMPLE_MEDIAN" ><\/a>PS_STAT_SAMPLE_MEDIAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a3	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a3" doxytag="PS_STAT_SAMPLE_STDEV" ><\/a>PS_STAT_SAMPLE_STDEV<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a4	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a4" doxytag="PS_STAT_SAMPLE_QUARTILE" ><\/a>PS_STAT_SAMPLE_QUARTILE<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a5	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a5" doxytag="PS_STAT_ROBUST_MEAN" ><\/a>PS_STAT_ROBUST_MEAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a6	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a6" doxytag="PS_STAT_ROBUST_MEDIAN" ><\/a>PS_STAT_ROBUST_MEDIAN<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a7	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a7" doxytag="PS_STAT_ROBUST_MODE" ><\/a>PS_STAT_ROBUST_MODE<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a8	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a8" doxytag="PS_STAT_ROBUST_STDEV" ><\/a>PS_STAT_ROBUST_STDEV<\/em>&nbsp;<\/td><td>$/;"	a
+gga61a9	docs/html/group__Stats.html	/^<tr><td valign=top><em><a class="anchor" name="gga61a9" doxytag="PS_STAT_ROBUST_QUARTILE" ><\/a>PS_STAT_ROBUST_QUARTILE<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a67	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a67" doxytag="PS_TYPE_S8" ><\/a>PS_TYPE_S8<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a68	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a68" doxytag="PS_TYPE_S16" ><\/a>PS_TYPE_S16<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a69	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a69" doxytag="PS_TYPE_S32" ><\/a>PS_TYPE_S32<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a70	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a70" doxytag="PS_TYPE_S64" ><\/a>PS_TYPE_S64<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a71	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a71" doxytag="PS_TYPE_U8" ><\/a>PS_TYPE_U8<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a72	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a72" doxytag="PS_TYPE_U16" ><\/a>PS_TYPE_U16<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a73	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a73" doxytag="PS_TYPE_U32" ><\/a>PS_TYPE_U32<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a74	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a74" doxytag="PS_TYPE_U64" ><\/a>PS_TYPE_U64<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a75	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a75" doxytag="PS_TYPE_F32" ><\/a>PS_TYPE_F32<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a76	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a76" doxytag="PS_TYPE_F64" ><\/a>PS_TYPE_F64<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a77	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a77" doxytag="PS_TYPE_C32" ><\/a>PS_TYPE_C32<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a78	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a78" doxytag="PS_TYPE_C64" ><\/a>PS_TYPE_C64<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a79	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a79" doxytag="PS_TYPE_BOOL" ><\/a>PS_TYPE_BOOL<\/em>&nbsp;<\/td><td>$/;"	a
+gga67a80	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga67a80" doxytag="PS_TYPE_PTR" ><\/a>PS_TYPE_PTR<\/em>&nbsp;<\/td><td>$/;"	a
+gga68a81	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga68a81" doxytag="PS_DIMEN_SCALAR" ><\/a>PS_DIMEN_SCALAR<\/em>&nbsp;<\/td><td>$/;"	a
+gga68a82	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga68a82" doxytag="PS_DIMEN_VECTOR" ><\/a>PS_DIMEN_VECTOR<\/em>&nbsp;<\/td><td>$/;"	a
+gga68a83	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga68a83" doxytag="PS_DIMEN_TRANSV" ><\/a>PS_DIMEN_TRANSV<\/em>&nbsp;<\/td><td>$/;"	a
+gga68a84	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga68a84" doxytag="PS_DIMEN_IMAGE" ><\/a>PS_DIMEN_IMAGE<\/em>&nbsp;<\/td><td>$/;"	a
+gga68a85	docs/html/group__DataContainer.html	/^<tr><td valign=top><em><a class="anchor" name="gga68a85" doxytag="PS_DIMEN_OTHER" ><\/a>PS_DIMEN_OTHER<\/em>&nbsp;<\/td><td>$/;"	a
+globalLogLevel	src/sysUtils/psLogMsg.c	/^static psS32 globalLogLevel = PS_LOG_INFO;        \/\/ log all messages at this or above$/;"	v	file:
+grommit	include/psAstrometry.h	/^    psGrommit *grommit;                \/\/\/< Wallace's grommit$/;"	m	struct:psFPA
+grommit	src/astronomy/psAstrometry.h	/^    psGrommit *grommit;                \/\/\/< Wallace's grommit$/;"	m	struct:psFPA
+gsl	include/psRandom.h	/^    gsl_rng *gsl; \/\/\/< The RNG itself$/;"	m
+gsl	src/dataManip/psRandom.h	/^    gsl_rng *gsl; \/\/\/< The RNG itself$/;"	m
+gslMatrixToPsImage	src/dataManip/psMatrix.c	/^static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix)$/;"	f	file:
+gslMatrixToPsImage	src/dataManip/psMatrix.c	/^static void gslMatrixToPsImage(psImage *outImage, gsl_matrix *inGslMatrix);$/;"	p	file:
+gslVectorToPsVector	src/dataManip/psMatrix.c	/^static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector)$/;"	f	file:
+gslVectorToPsVector	src/dataManip/psMatrix.c	/^static void gslVectorToPsVector(psVector *outVector, gsl_vector *inGslVector);$/;"	p	file:
+hashBucketAlloc	src/collections/psHash.c	/^static psHashBucket* hashBucketAlloc(const char *key, psPtr data, psHashBucket* next);$/;"	p	file:
+hashBucketAlloc	src/collections/psHash.c	/^static psHashBucket* hashBucketAlloc(const char *key,$/;"	f	file:
+hashBucketFree	src/collections/psHash.c	/^static void hashBucketFree(psHashBucket* bucket)$/;"	f	file:
+hashBucketFree	src/collections/psHash.c	/^static void hashBucketFree(psHashBucket* bucket);$/;"	p	file:
+hashFree	src/collections/psHash.c	/^static void hashFree(psHash* table)$/;"	f	file:
+hashFree	src/collections/psHash.c	/^static void hashFree(psHash* table);$/;"	p	file:
+head	include/psList.h	/^    psListElem* head;                  \/\/\/< first element on list (may be NULL)$/;"	m
+head	src/collections/psList.h	/^    psListElem* head;                  \/\/\/< first element on list (may be NULL)$/;"	m
+height	include/psAstrometry.h	/^    const double height;               \/\/\/< Height of observatory in meters$/;"	m
+height	include/psAstrometry.h	/^    const double height;               \/\/\/< height (HM)$/;"	m
+height	src/astronomy/psAstrometry.h	/^    const double height;               \/\/\/< Height of observatory in meters$/;"	m
+height	src/astronomy/psAstrometry.h	/^    const double height;               \/\/\/< height (HM)$/;"	m
+histogramFree	src/dataManip/psStats.c	/^static void histogramFree(psHistogram* myHist)$/;"	f	file:
+histogramFree	src/dataManip/psStats.c	/^static void histogramFree(psHistogram* myHist);$/;"	p	file:
+hourAngle	include/psAstrometry.h	/^    const double hourAngle;            \/\/\/< Hour angle$/;"	m	struct:psExposure
+hourAngle	src/astronomy/psAstrometry.h	/^    const double hourAngle;            \/\/\/< Hour angle$/;"	m	struct:psExposure
+humidity	include/psAstrometry.h	/^    const double humidity;             \/\/\/< relative humidity (RH)$/;"	m
+humidity	include/psAstrometry.h	/^    const float humidity;              \/\/\/< Relative humidity, for refraction$/;"	m	struct:psExposure
+humidity	src/astronomy/psAstrometry.h	/^    const double humidity;             \/\/\/< relative humidity (RH)$/;"	m
+humidity	src/astronomy/psAstrometry.h	/^    const float humidity;              \/\/\/< Relative humidity, for refraction$/;"	m	struct:psExposure
+id	include/psMemory.h	/^    const psMemoryId id;               \/\/\/< a unique ID for this allocation$/;"	m	struct:psMemBlock
+id	include/psMetadata.h	/^    const psS32 id;                    \/\/\/< Unique ID for metadata item.$/;"	m	struct:psMetadataItem
+id	src/astronomy/psMetadata.h	/^    const psS32 id;                    \/\/\/< Unique ID for metadata item.$/;"	m	struct:psMetadataItem
+id	src/sysUtils/psMemory.h	/^    const psMemoryId id;               \/\/\/< a unique ID for this allocation$/;"	m	struct:psMemBlock
+ignoreLine	src/astronomy/psMetadataIO.c	/^psBool ignoreLine(char *inString)$/;"	f
+ignoreLine	src/fileUtils/psLookupTable.c	/^static bool ignoreLine(char *inString)$/;"	f	file:
+ignoreLine	src/fileUtils/psLookupTable.c	/^static bool ignoreLine(char *inString);$/;"	p	file:
+imGlobal	test/collections/tst_psHash01.c	/^psS32 imGlobal = 0;$/;"	v
+imGlobal	test/collections/tst_psHash02.c	/^psS32 imGlobal = 0;$/;"	v
+imGlobal	test/collections/tst_psHash03.c	/^psS32 imGlobal = 0;$/;"	v
+imGlobal	test/collections/tst_psHash04.c	/^psS32 imGlobal = 0;$/;"	v
+image	include/psAstrometry.h	/^    psImage* image;                    \/\/\/< Imaging area of readout$/;"	m
+image	include/psImageConvolve.h	/^    psImage* image;                    \/\/\/< Kernel data, in the form of an image$/;"	m
+image	src/astronomy/psAstrometry.h	/^    psImage* image;                    \/\/\/< Imaging area of readout$/;"	m
+image	src/image/psImageConvolve.h	/^    psImage* image;                    \/\/\/< Kernel data, in the form of an image$/;"	m
+imageFree	src/image/psImage.c	/^static void imageFree(psImage* image)$/;"	f	file:
+imageSubset	src/image/psImageExtraction.c	/^psImage* imageSubset(psImage* out,$/;"	f
+index	include/psList.h	/^int index;                         \/\/\/< the index number in the list$/;"	m
+index	include/psLookupTable.h	/^    psVector *index;                   \/\/\/< Vector of independent index values$/;"	m
+index	src/collections/psList.h	/^int index;                         \/\/\/< the index number in the list$/;"	m
+index	src/fileUtils/psLookupTable.h	/^    psVector *index;                   \/\/\/< Vector of independent index values$/;"	m
+index_a	docs/html/functions.html	/^Here is a list of all struct and union fields with links to the structures\/unions they belong to:<h3><a class="anchor" name="index_a">- a -<\/a><\/h3><ul>$/;"	a
+index_a	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_a">- a -<\/a><\/h3><ul>$/;"	a
+index_b	docs/html/functions.html	/^<h3><a class="anchor" name="index_b">- b -<\/a><\/h3><ul>$/;"	a
+index_b	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_b">- b -<\/a><\/h3><ul>$/;"	a
+index_c	docs/html/functions.html	/^<h3><a class="anchor" name="index_c">- c -<\/a><\/h3><ul>$/;"	a
+index_c	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_c">- c -<\/a><\/h3><ul>$/;"	a
+index_d	docs/html/functions.html	/^<h3><a class="anchor" name="index_d">- d -<\/a><\/h3><ul>$/;"	a
+index_d	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_d">- d -<\/a><\/h3><ul>$/;"	a
+index_e	docs/html/functions.html	/^<h3><a class="anchor" name="index_e">- e -<\/a><\/h3><ul>$/;"	a
+index_e	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_e">- e -<\/a><\/h3><ul>$/;"	a
+index_f	docs/html/functions.html	/^<h3><a class="anchor" name="index_f">- f -<\/a><\/h3><ul>$/;"	a
+index_f	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_f">- f -<\/a><\/h3><ul>$/;"	a
+index_f	docs/html/globals.html	/^Here is a list of all functions, variables, defines, enums, and typedefs with links to the files they belong to:<h3><a class="anchor" name="index_f">- f -<\/a><\/h3><ul>$/;"	a
+index_f	docs/html/globals_defs.html	/^<h3><a class="anchor" name="index_f">- f -<\/a><\/h3><ul>$/;"	a
+index_f	docs/html/globals_func.html	/^<h3><a class="anchor" name="index_f">- f -<\/a><\/h3><ul>$/;"	a
+index_g	docs/html/functions.html	/^<h3><a class="anchor" name="index_g">- g -<\/a><\/h3><ul>$/;"	a
+index_g	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_g">- g -<\/a><\/h3><ul>$/;"	a
+index_h	docs/html/functions.html	/^<h3><a class="anchor" name="index_h">- h -<\/a><\/h3><ul>$/;"	a
+index_h	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_h">- h -<\/a><\/h3><ul>$/;"	a
+index_i	docs/html/functions.html	/^<h3><a class="anchor" name="index_i">- i -<\/a><\/h3><ul>$/;"	a
+index_i	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_i">- i -<\/a><\/h3><ul>$/;"	a
+index_k	docs/html/functions.html	/^<h3><a class="anchor" name="index_k">- k -<\/a><\/h3><ul>$/;"	a
+index_k	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_k">- k -<\/a><\/h3><ul>$/;"	a
+index_l	docs/html/functions.html	/^<h3><a class="anchor" name="index_l">- l -<\/a><\/h3><ul>$/;"	a
+index_l	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_l">- l -<\/a><\/h3><ul>$/;"	a
+index_m	docs/html/functions.html	/^<h3><a class="anchor" name="index_m">- m -<\/a><\/h3><ul>$/;"	a
+index_m	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_m">- m -<\/a><\/h3><ul>$/;"	a
+index_n	docs/html/functions.html	/^<h3><a class="anchor" name="index_n">- n -<\/a><\/h3><ul>$/;"	a
+index_n	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_n">- n -<\/a><\/h3><ul>$/;"	a
+index_o	docs/html/functions.html	/^<h3><a class="anchor" name="index_o">- o -<\/a><\/h3><ul>$/;"	a
+index_o	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_o">- o -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/functions.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/globals.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/globals_defs.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/globals_eval.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/globals_func.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_p	docs/html/globals_type.html	/^<h3><a class="anchor" name="index_p">- p -<\/a><\/h3><ul>$/;"	a
+index_r	docs/html/functions.html	/^<h3><a class="anchor" name="index_r">- r -<\/a><\/h3><ul>$/;"	a
+index_r	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_r">- r -<\/a><\/h3><ul>$/;"	a
+index_s	docs/html/functions.html	/^<h3><a class="anchor" name="index_s">- s -<\/a><\/h3><ul>$/;"	a
+index_s	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_s">- s -<\/a><\/h3><ul>$/;"	a
+index_s	docs/html/globals.html	/^<h3><a class="anchor" name="index_s">- s -<\/a><\/h3><ul>$/;"	a
+index_s	docs/html/globals_defs.html	/^<h3><a class="anchor" name="index_s">- s -<\/a><\/h3><ul>$/;"	a
+index_t	docs/html/functions.html	/^<h3><a class="anchor" name="index_t">- t -<\/a><\/h3><ul>$/;"	a
+index_t	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_t">- t -<\/a><\/h3><ul>$/;"	a
+index_u	docs/html/functions.html	/^<h3><a class="anchor" name="index_u">- u -<\/a><\/h3><ul>$/;"	a
+index_u	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_u">- u -<\/a><\/h3><ul>$/;"	a
+index_v	docs/html/functions.html	/^<h3><a class="anchor" name="index_v">- v -<\/a><\/h3><ul>$/;"	a
+index_v	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_v">- v -<\/a><\/h3><ul>$/;"	a
+index_w	docs/html/functions.html	/^<h3><a class="anchor" name="index_w">- w -<\/a><\/h3><ul>$/;"	a
+index_w	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_w">- w -<\/a><\/h3><ul>$/;"	a
+index_x	docs/html/functions.html	/^<h3><a class="anchor" name="index_x">- x -<\/a><\/h3><ul>$/;"	a
+index_x	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_x">- x -<\/a><\/h3><ul>$/;"	a
+index_y	docs/html/functions.html	/^<h3><a class="anchor" name="index_y">- y -<\/a><\/h3><ul>$/;"	a
+index_y	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_y">- y -<\/a><\/h3><ul>$/;"	a
+index_z	docs/html/functions.html	/^<h3><a class="anchor" name="index_z">- z -<\/a><\/h3><ul>$/;"	a
+index_z	docs/html/functions_vars.html	/^<h3><a class="anchor" name="index_z">- z -<\/a><\/h3><ul>$/;"	a
+initTrace	src/sysUtils/psTrace.c	/^static void initTrace(void)$/;"	f	file:
+install	docs/html/index.html	/^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.<h2><a class="anchor" name="install">$/;"	a
+interpolate1DF32	src/dataManip/psFunctions.c	/^static psF32 interpolate1DF32(psF32 *domain,$/;"	f	file:
+intro	docs/html/index.html	/^<h3 align="center">V1.2-R3 <\/h3><h2><a class="anchor" name="intro">$/;"	a
+invertPlaneTransform	src/astronomy/psAstrometry.c	/^static psPlaneTransform *invertPlaneTransform(psPlaneTransform *transform)$/;"	f	file:
+isDuplicateEntry	include/psTest.h	/^    psBool      isDuplicateEntry;$/;"	m
+isDuplicateEntry	test/psTest.h	/^    psBool      isDuplicateEntry;$/;"	m
+isHDUEmpty	src/fileUtils/psFits.c	/^static bool isHDUEmpty(psFits* fits)$/;"	f	file:
+isProjectionLinear	src/astronomy/psAstrometry.c	/^static psS32 isProjectionLinear(psPlaneTransform *transform)$/;"	f	file:
+iter	include/psMinimize.h	/^    psS32 iter;                          \/\/\/< Number of iterations required$/;"	m
+iter	src/dataManip/psMinimize.h	/^    psS32 iter;                          \/\/\/< Number of iterations required$/;"	m
+iterators	include/psList.h	/^    psArray* iterators;$/;"	m
+iterators	src/collections/psList.h	/^    psArray* iterators;$/;"	m
+kernel	include/psImageConvolve.h	/^    psKernelType** kernel;             \/\/\/< Pointer to the kernel data$/;"	m
+kernel	src/image/psImageConvolve.h	/^    psKernelType** kernel;             \/\/\/< Pointer to the kernel data$/;"	m
+key	include/psHash.h	/^    char *key;                  \/\/\/< key for this item of data$/;"	m	struct:psHashBucket
+key	src/collections/psHash.h	/^    char *key;                  \/\/\/< key for this item of data$/;"	m	struct:psHashBucket
+l00002	docs/html/psList_8h-source.html	/^<a name="l00002"><\/a><a class="code" href="psList_8h.html#a0">00002<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_LIST_H<\/span>$/;"	a
+l00015	docs/html/psCompare_8h-source.html	/^<a name="l00015"><\/a><a class="code" href="psCompare_8h.html#a0">00015<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_COMPARE_H<\/span>$/;"	a
+l00017	docs/html/psConstants_8h-source.html	/^<a name="l00017"><\/a><a class="code" href="psConstants_8h.html#a0">00017<\/a> <span class="preprocessor">#define PS_DETERMINE_BRACKET_STEP_SIZE 0.10<\/span>$/;"	a
+l00017	docs/html/psImageStats_8h-source.html	/^<a name="l00017"><\/a><a class="code" href="psImageStats_8h.html#a0">00017<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_IMAGE_STATS_H<\/span>$/;"	a
+l00017	docs/html/psTrace_8h-source.html	/^<a name="l00017"><\/a><a class="code" href="psTrace_8h.html#a0">00017<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TRACE_H 1<\/span>$/;"	a
+l00018	docs/html/psConstants_8h-source.html	/^<a name="l00018"><\/a><a class="code" href="psConstants_8h.html#a1">00018<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_MAX_LMM_ITERATIONS 100<\/span>$/;"	a
+l00018	docs/html/psMinimize_8h-source.html	/^<a name="l00018"><\/a><a class="code" href="psMinimize_8h.html#a0">00018<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_MINIMIZE_H<\/span>$/;"	a
+l00018	docs/html/psStats_8h-source.html	/^<a name="l00018"><\/a><a class="code" href="psStats_8h.html#a0">00018<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_STATS_H<\/span>$/;"	a
+l00019	docs/html/psConstants_8h-source.html	/^<a name="l00019"><\/a><a class="code" href="psConstants_8h.html#a2">00019<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_MAX_MINIMIZE_ITERATIONS 100<\/span>$/;"	a
+l00019	docs/html/psHash_8h-source.html	/^<a name="l00019"><\/a><a class="code" href="psHash_8h.html#a0">00019<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_HASH_H<\/span>$/;"	a
+l00019	docs/html/psLogMsg_8h-source.html	/^<a name="l00019"><\/a><a class="code" href="psLogMsg_8h.html#a0">00019<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_LOG_MSG_H<\/span>$/;"	a
+l00019	docs/html/psRandom_8h-source.html	/^<a name="l00019"><\/a><a class="code" href="psRandom_8h.html#a0">00019<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_FUNCTIONS_H<\/span>$/;"	a
+l00019	docs/html/psTrace_8h-source.html	/^<a name="l00019"><\/a><a class="code" href="psTrace_8h.html#a1">00019<\/a> <span class="preprocessor">#define PS_UNKNOWN_TRACE_LEVEL -9999   \/\/ we don't know this name's level<\/span>$/;"	a
+l00020	docs/html/psConstants_8h-source.html	/^<a name="l00020"><\/a><a class="code" href="psConstants_8h.html#a3">00020<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_LEFT_SPLINE_DERIV 0.0<\/span>$/;"	a
+l00020	docs/html/psTrace_8h-source.html	/^<a name="l00020"><\/a><a class="code" href="psTrace_8h.html#a2">00020<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_DEFAULT_TRACE_LEVEL -1<\/span>$/;"	a
+l00021	docs/html/psConstants_8h-source.html	/^<a name="l00021"><\/a><a class="code" href="psConstants_8h.html#a4">00021<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_RIGHT_SPLINE_DERIV 0.0<\/span>$/;"	a
+l00021	docs/html/psFunctions_8h-source.html	/^<a name="l00021"><\/a><a class="code" href="psFunctions_8h.html#a0">00021<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_FUNCTIONS_H<\/span>$/;"	a
+l00021	docs/html/psMemory_8h-source.html	/^<a name="l00021"><\/a><a class="code" href="psMemory_8h.html#a0">00021<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_MEMORY_H<\/span>$/;"	a
+l00021	docs/html/psTrace_8h-source.html	/^<a name="l00021"><\/a><a class="code" href="psTrace_8h.html#a3">00021<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL 0<\/span>$/;"	a
+l00022	docs/html/psImageConvolve_8h-source.html	/^<a name="l00022"><\/a><a class="code" href="psImageConvolve_8h.html#a0">00022<\/a> <span class="preprocessor">#define PS_TYPE_KERNEL PS_TYPE_F32     <\/span><span class="comment">\/**&lt; the data member to use for kernel image *\/<\/span>$/;"	a
+l00023	docs/html/psImageConvolve_8h-source.html	/^<a name="l00023"><\/a><a class="code" href="psImageConvolve_8h.html#a1">00023<\/a> <span class="preprocessor">#define PS_TYPE_KERNEL_DATA F32        <\/span><span class="comment">\/**&lt; the data member to use for kernel image *\/<\/span>$/;"	a
+l00024	docs/html/psImageConvolve_8h-source.html	/^<a name="l00024"><\/a><a class="code" href="psImageConvolve_8h.html#a2">00024<\/a> <span class="preprocessor">#define PS_TYPE_KERNEL_NAME "psF32"    <\/span><span class="comment">\/**&lt; the data type for kernel as a string *\/<\/span>$/;"	a
+l00024	docs/html/psString_8h-source.html	/^<a name="l00024"><\/a><a class="code" href="psString_8h.html#a0">00024<\/a> <span class="preprocessor">#define PS_STRING(S)  #S<\/span>$/;"	a
+l00024	docs/html/psVectorFFT_8h-source.html	/^<a name="l00024"><\/a><a class="code" href="group__Transform.html#ga12">00024<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {<span class="comment"><\/span>$/;"	a
+l00025	docs/html/psConstants_8h-source.html	/^<a name="l00025"><\/a><a class="code" href="psConstants_8h.html#a5">00025<\/a> <span class="preprocessor">#define PS_ONE 1.0<\/span>$/;"	a
+l00026	docs/html/psImageConvolve_8h-source.html	/^<a name="l00026"><\/a><a class="code" href="psImageConvolve_8h.html#a3">00026<\/a> <span class="keyword">typedef<\/span> <a class="code" href="group__DataContainer.html#ga8">psF32<\/a> <a class="code" href="psImageConvolve_8h.html#a3">psKernelType<\/a>;$/;"	a
+l00028	docs/html/psHash_8h-source.html	/^<a name="l00028"><\/a><a class="code" href="structpsHashBucket.html">00028<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsHashBucket.html">psHashBucket<\/a>$/;"	a
+l00029	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="psAstronomyErrors_8h.html#a0">00029<\/a> <span class="preprocessor">#define PS_ERRORNAME_DOMAIN "psLib.astronomy."<\/span>$/;"	a
+l00029	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="psCollectionsErrors_8h.html#a0">00029<\/a> <span class="preprocessor">#define PS_ERRORNAME_DOMAIN "psLib.collections."<\/span>$/;"	a
+l00029	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="psDataManipErrors_8h.html#a0">00029<\/a> <span class="preprocessor">#define PS_ERRORNAME_DOMAIN "psLib.dataManip."<\/span>$/;"	a
+l00029	docs/html/psImageConvolve_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="structpsKernel.html">00029<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00029	docs/html/psImageErrors_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="psImageErrors_8h.html#a0">00029<\/a> <span class="preprocessor">#define PS_ERRORNAME_DOMAIN "psLib.image."<\/span>$/;"	a
+l00029	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00029"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a0">00029<\/a> <span class="preprocessor">#define PS_ERRORNAME_DOMAIN "psLib.sysUtils."<\/span>$/;"	a
+l00030	docs/html/psCompare_8h-source.html	/^<a name="l00030"><\/a><a class="code" href="group__Compare.html#ga0">00030<\/a> <span class="keyword">typedef<\/span> int (*<a class="code" href="group__Compare.html#ga0">psComparePtrFcn<\/a>) ($/;"	a
+l00030	docs/html/psHash_8h-source.html	/^<a name="l00030"><\/a><a class="code" href="structpsHashBucket.html#o0">00030<\/a>     <span class="keywordtype">char<\/span> *<a class="code" href="structpsHashBucket.html#o0">key<\/a>;                  <span class="comment">\/\/\/&lt; key for this item of data<\/span>$/;"	a
+l00030	docs/html/psImageExtraction_8h-source.html	/^<a name="l00030"><\/a><a class="code" href="group__Image.html#ga26">00030<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00031	docs/html/psConstants_8h-source.html	/^<a name="l00031"><\/a><a class="code" href="psConstants_8h.html#a6">00031<\/a> <span class="preprocessor">#define PS_INT_CHECK_EQUALS(NAME1, NAME2, RVAL) \\<\/span>$/;"	a
+l00031	docs/html/psHash_8h-source.html	/^<a name="l00031"><\/a><a class="code" href="structpsHashBucket.html#o1">00031<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsHashBucket.html#o1">data<\/a>;                 <span class="comment">\/\/\/&lt; the data itself<\/span>$/;"	a
+l00031	docs/html/psImageConvolve_8h-source.html	/^<a name="l00031"><\/a><a class="code" href="structpsKernel.html#o0">00031<\/a>     <a class="code" href="structpsImage.html">psImage<\/a>* image;                    <span class="comment">\/\/\/&lt; Kernel data, in the form of an image<\/span>$/;"	a
+l00032	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="psAstronomyErrors_8h.html#a1">00032<\/a> <span class="preprocessor">#define PS_ERRORTEXT_psTime_FILE_NOT_FOUND "Failed to open file %s."<\/span>$/;"	a
+l00032	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="psCollectionsErrors_8h.html#a1">00032<\/a> <span class="preprocessor"> #define PS_ERRORTEXT_psArray_REALLOC_NULL "psArrayRealloc must be given a non-NULL psArray to resize."<\/span>$/;"	a
+l00032	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="psDataManipErrors_8h.html#a1">00032<\/a> <span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_TYPE_NOT_F32_C32 "Input psVector type, %s, is not supported. Valid data types are psF32 and psC32."<\/span>$/;"	a
+l00032	docs/html/psHash_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="structpsHashBucket.html#o2">00032<\/a> <span class="comment"><\/span>    <span class="keyword">struct <\/span><a class="code" href="structpsHashBucket.html">psHashBucket<\/a>* <a class="code" href="structpsHashBucket.html#o2">next<\/a>;  <span class="comment">\/\/\/&lt; list of other possible keys<\/span>$/;"	a
+l00032	docs/html/psImageConvolve_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="structpsKernel.html#o1">00032<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> xMin;                          <span class="comment">\/\/\/&lt; Most negative x index<\/span>$/;"	a
+l00032	docs/html/psImageErrors_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="psImageErrors_8h.html#a1">00032<\/a> <span class="preprocessor">#define PS_ERRORTEXT_psImage_AREA_NEGATIVE "Specified number of rows (%d) or columns (%d) is invalid."<\/span>$/;"	a
+l00032	docs/html/psImage_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="group__Image.html#ga25">00032<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00032	docs/html/psScalar_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="structpsScalar.html">00032<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00032	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a1">00032<\/a> <span class="preprocessor">#define PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED "The specified destination, %s, is malformed."<\/span>$/;"	a
+l00032	docs/html/psVector_8h-source.html	/^<a name="l00032"><\/a><a class="code" href="structpsVector.html">00032<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00033	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="psAstronomyErrors_8h.html#a2">00033<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_FILE_TOO_MANY_ROWS "Too many rows found in file %s. Max number of rows allowed is %d."<\/span>$/;"	a
+l00033	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="psCollectionsErrors_8h.html#a2">00033<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psVector_REALLOC_NULL "psVectorRealloc must a given a non-NULL psVector to resize.  Desired datatype unknown."<\/span>$/;"	a
+l00033	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="psDataManipErrors_8h.html#a2">00033<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_REVERSE_NOT_COMPLEX "Input psVector (%s) is not complex.  Reverse FFT operation requires a complex input."<\/span>$/;"	a
+l00033	docs/html/psImageConvolve_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="structpsKernel.html#o2">00033<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> yMin;                          <span class="comment">\/\/\/&lt; Most negative y index<\/span>$/;"	a
+l00033	docs/html/psImageErrors_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="psImageErrors_8h.html#a2">00033<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_NOT_AN_IMAGE "The input psImage must have a PS_DIMEN_IMAGE dimension type."<\/span>$/;"	a
+l00033	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00033"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a2">00033<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID "The location, %s, for protocol 'dest' is invalid."<\/span>$/;"	a
+l00034	docs/html/psArray_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="structpsArray.html">00034<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00034	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="psAstronomyErrors_8h.html#a3">00034<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLE "Specified psTime postdates (%g) the table of %s information."<\/span>$/;"	a
+l00034	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="psCollectionsErrors_8h.html#a3">00034<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psVector_NOT_A_VECTOR "The input psVector must have a vector dimension type."<\/span>$/;"	a
+l00034	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="psDataManipErrors_8h.html#a3">00034<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_FORWARD_NOT_REAL "Input psVector (%s) is not real.  Forward FFT operation requires a real input."<\/span>$/;"	a
+l00034	docs/html/psError_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="structpsErr.html">00034<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00034	docs/html/psImageConvolve_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="structpsKernel.html#o3">00034<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> xMax;                          <span class="comment">\/\/\/&lt; Most positive x index<\/span>$/;"	a
+l00034	docs/html/psImageErrors_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="psImageErrors_8h.html#a3">00034<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_IMAGE_NULL "Can not operate on a NULL psImage."<\/span>$/;"	a
+l00034	docs/html/psMetadata_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="group__Metadata.html#ga17">00034<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00034	docs/html/psScalar_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="structpsScalar.html#o0">00034<\/a>     <a class="code" href="structpsType.html">psType<\/a> type;                <span class="comment">\/\/\/&lt; Type of data.<\/span>$/;"	a
+l00034	docs/html/psStats_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="group__Stats.html#ga61">00034<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00034	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a3">00034<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED "Could not open file '%s' for output."<\/span>$/;"	a
+l00034	docs/html/psVector_8h-source.html	/^<a name="l00034"><\/a><a class="code" href="structpsVector.html#o0">00034<\/a>     <a class="code" href="structpsType.html">psType<\/a> type;                <span class="comment">\/\/\/&lt; Type of data.<\/span>$/;"	a
+l00035	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="psAstronomyErrors_8h.html#a4">00035<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLE "Specified psTime predates (%g) the table of %s information."<\/span>$/;"	a
+l00035	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="psCollectionsErrors_8h.html#a4">00035<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psVector_SORT_NULL "psVectorSort can not sort a NULL psVector."<\/span>$/;"	a
+l00035	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="psDataManipErrors_8h.html#a4">00035<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL "Could not create a valid FFT plan to perform the transform."<\/span>$/;"	a
+l00035	docs/html/psImageConvolve_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="structpsKernel.html#o4">00035<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> yMax;                          <span class="comment">\/\/\/&lt; Most positive y index<\/span>$/;"	a
+l00035	docs/html/psImageErrors_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="psImageErrors_8h.html#a4">00035<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED "Specified psImage type, %s, is not supported."<\/span>$/;"	a
+l00035	docs/html/psRandom_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="group__Math.html#ga5">00035<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00035	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a4">00035<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL "Do not know how to handle the protocol '%s'."<\/span>$/;"	a
+l00035	docs/html/psVector_8h-source.html	/^<a name="l00035"><\/a><a class="code" href="structpsVector.html#o1">00035<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> nalloc;        <span class="comment">\/\/\/&lt; Total number of elements available.<\/span>$/;"	a
+l00036	docs/html/psArray_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="structpsArray.html#o0">00036<\/a>     <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> nalloc;        <span class="comment">\/\/\/&lt; Total number of elements available.<\/span>$/;"	a
+l00036	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="psAstronomyErrors_8h.html#a5">00036<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TIME_POSTDATES_TABLES "Specified psTime postdates (%g) all tables of %s information."<\/span>$/;"	a
+l00036	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="psCollectionsErrors_8h.html#a5">00036<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE "Input psVector is an unsupported type (%d)."<\/span>$/;"	a
+l00036	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="psDataManipErrors_8h.html#a5">00036<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED "Specified psVector type, %s, is not supported."<\/span>$/;"	a
+l00036	docs/html/psError_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="structpsErr.html#o0">00036<\/a>     <span class="keywordtype">char<\/span>* name;                        <span class="comment">\/\/\/&lt; category of code that caused the error<\/span>$/;"	a
+l00036	docs/html/psImageConvolve_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="structpsKernel.html#o5">00036<\/a> <span class="comment"><\/span>    <a class="code" href="psImageConvolve_8h.html#a3">psKernelType<\/a>** kernel;             <span class="comment">\/\/\/&lt; Pointer to the kernel data<\/span>$/;"	a
+l00036	docs/html/psImageErrors_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="psImageErrors_8h.html#a5">00036<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID "Specified interpolation method (%d) is not supported."<\/span>$/;"	a
+l00036	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a5">00036<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY "Unknown logging keyword %c."<\/span>$/;"	a
+l00036	docs/html/psVector_8h-source.html	/^<a name="l00036"><\/a><a class="code" href="structpsVector.html#o2">00036<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> n;             <span class="comment">\/\/\/&lt; Number of elements in use.<\/span>$/;"	a
+l00037	docs/html/psArray_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="structpsArray.html#o1">00037<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> n;             <span class="comment">\/\/\/&lt; Number of elements in use.<\/span>$/;"	a
+l00037	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="psAstronomyErrors_8h.html#a6">00037<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TIME_PREDATES_TABLES "Specified psTime predates (%g) all tables of %s information."<\/span>$/;"	a
+l00037	docs/html/psBitSet_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="structpsBitSet.html">00037<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00037	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="psCollectionsErrors_8h.html#a6">00037<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE "The number of bit in a psBitSet (%d) must be greater than zero."<\/span>$/;"	a
+l00037	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="psDataManipErrors_8h.html#a6">00037<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH "Real psVector type, %s, and imaginary psVector type, %s, must be the same."<\/span>$/;"	a
+l00037	docs/html/psErrorCodes_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="group__ErrorHandling.html#ga13">00037<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00037	docs/html/psError_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="structpsErr.html#o1">00037<\/a> <span class="comment"><\/span>    <a class="code" href="group__ErrorHandling.html#ga13">psErrorCode<\/a> code;                  <span class="comment">\/\/\/&lt; class of error<\/span>$/;"	a
+l00037	docs/html/psImageConvolve_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="structpsKernel.html#o6">00037<\/a> <span class="comment"><\/span>    <a class="code" href="psImageConvolve_8h.html#a3">psKernelType<\/a>** p_kernelRows;       <span class="comment">\/\/\/&lt; Pointer to the rows of the kernel data; not intended for user use.<\/span>$/;"	a
+l00037	docs/html/psImageErrors_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="psImageErrors_8h.html#a6">00037<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#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]."<\/span>$/;"	a
+l00037	docs/html/psScalar_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="structpsScalar.html#o1">00037<\/a>         <a class="code" href="group__DataContainer.html#ga0">psU8<\/a> U8;                <span class="comment">\/\/\/&lt; Unsigned 8-bit integer data.<\/span>$/;"	a
+l00037	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00037"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a6">00037<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMemory_NULL_BLOCK "NULL memory block found."<\/span>$/;"	a
+l00038	docs/html/psArray_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="structpsArray.html#o2">00038<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a>* data;                <span class="comment">\/\/\/&lt; An Array of pointer elements<\/span>$/;"	a
+l00038	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="psAstronomyErrors_8h.html#a7">00038<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TABLE_DUPLICATE_ROWS "The %s table was found to have two rows of the same time value."<\/span>$/;"	a
+l00038	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="psCollectionsErrors_8h.html#a7">00038<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_SET_NULL "Can not operate on a NULL psBitSet."<\/span>$/;"	a
+l00038	docs/html/psCoord_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="structpsPlane.html">00038<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00038	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="psDataManipErrors_8h.html#a7">00038<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_SIZE_MISMATCH "Real psVector size, %d, and imaginary psVector size, %d, must be the same."<\/span>$/;"	a
+l00038	docs/html/psError_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="structpsErr.html#o2">00038<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span>* msg;                         <span class="comment">\/\/\/&lt; the message associated with the error<\/span>$/;"	a
+l00038	docs/html/psImageErrors_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="psImageErrors_8h.html#a7">00038<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED "Specified subset range, [%d:%d,%d:%d], is invalid.  Ranges must be incremental."<\/span>$/;"	a
+l00038	docs/html/psScalar_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="structpsScalar.html#o2">00038<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga1">psU16<\/a> U16;              <span class="comment">\/\/\/&lt; Unsigned 16-bit integer data.<\/span>$/;"	a
+l00038	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00038"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a7">00038<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE "Memory block %lld was freed but still being used."<\/span>$/;"	a
+l00039	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psAstronomyErrors_8h.html#a8">00039<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TYPE_UNKNOWN "Specified type, %d, is not supported."<\/span>$/;"	a
+l00039	docs/html/psBitSet_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsBitSet.html#o0">00039<\/a>     <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> n;                             <span class="comment">\/\/\/&lt; Number of bytes in the array<\/span>$/;"	a
+l00039	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psCollectionsErrors_8h.html#a8">00039<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE "The specified bit position (%d) is invalid.  Position must be between 0 and %d."<\/span>$/;"	a
+l00039	docs/html/psConstants_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psConstants_8h.html#a7">00039<\/a> <span class="preprocessor">#define PS_INT_CHECK_NON_NEGATIVE(NAME, RVAL) \\<\/span>$/;"	a
+l00039	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psDataManipErrors_8h.html#a8">00039<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED "Input psVector type, %s, is required to be either psF32 or psF64."<\/span>$/;"	a
+l00039	docs/html/psHash_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsHash.html">00039<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsHash.html">psHash<\/a>$/;"	a
+l00039	docs/html/psImageErrors_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psImageErrors_8h.html#a8">00039<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_SUBSECTION_NULL "Specified subsection string can not be NULL."<\/span>$/;"	a
+l00039	docs/html/psList_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsListElem.html">00039<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsListElem.html">psListElem<\/a> {$/;"	a
+l00039	docs/html/psMinimize_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsMinimization.html">00039<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00039	docs/html/psRandom_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsRandom.html">00039<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00039	docs/html/psScalar_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsScalar.html#o3">00039<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> U32;              <span class="comment">\/\/\/&lt; Unsigned 32-bit integer data.<\/span>$/;"	a
+l00039	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a8">00039<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMemory_UNDERFLOW "Memory block %lld is corrupted; buffer underflow detected."<\/span>$/;"	a
+l00039	docs/html/psVector_8h-source.html	/^<a name="l00039"><\/a><a class="code" href="structpsVector.html#o3">00039<\/a>         <a class="code" href="group__DataContainer.html#ga0">psU8<\/a>* U8;               <span class="comment">\/\/\/&lt; Unsigned 8-bit integer data.<\/span>$/;"	a
+l00040	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="psAstronomyErrors_8h.html#a9">00040<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TYPE_INCORRECT "Specified type, %d, is incorrect."<\/span>$/;"	a
+l00040	docs/html/psBitSet_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="structpsBitSet.html#o1">00040<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> *bits;                        <span class="comment">\/\/\/&lt; Aray of bytes holding bits<\/span>$/;"	a
+l00040	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="psCollectionsErrors_8h.html#a9">00040<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_OPERATOR_NULL "Specified operator is NULL.  Must specify desired operator."<\/span>$/;"	a
+l00040	docs/html/psCoord_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="structpsPlane.html#o0">00040<\/a>     <span class="keywordtype">double<\/span> x;                   <span class="comment">\/\/\/&lt; x position<\/span>$/;"	a
+l00040	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="psDataManipErrors_8h.html#a9">00040<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED "Input psVector type, %s, is required to be either psC32 or psC64."<\/span>$/;"	a
+l00040	docs/html/psImageErrors_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="psImageErrors_8h.html#a9">00040<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_SUBSECTION_INVALID "Specified subsection string, '%s', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'."<\/span>$/;"	a
+l00040	docs/html/psList_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="structpsListElem.html#o0">00040<\/a>     <span class="keyword">struct <\/span><a class="code" href="structpsListElem.html">psListElem<\/a>* <a class="code" href="structpsListElem.html#o0">prev<\/a>;           <span class="comment">\/\/\/&lt; previous link in list<\/span>$/;"	a
+l00040	docs/html/psScalar_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="structpsScalar.html#o4">00040<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga3">psU64<\/a> U64;              <span class="comment">\/\/\/&lt; Unsigned 64-bit integer data.<\/span>$/;"	a
+l00040	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a9">00040<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMemory_OVERFLOW "Memory block %lld is corrupted; buffer overflow detected."<\/span>$/;"	a
+l00040	docs/html/psVector_8h-source.html	/^<a name="l00040"><\/a><a class="code" href="structpsVector.html#o4">00040<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga1">psU16<\/a>* U16;             <span class="comment">\/\/\/&lt; Unsigned 16-bit integer data.<\/span>$/;"	a
+l00041	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="psAstronomyErrors_8h.html#a10">00041<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_TYPE_MISMATCH "Specified psTime parameters must have same type."<\/span>$/;"	a
+l00041	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="psCollectionsErrors_8h.html#a10">00041<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_OPERATOR_INVALID "Specified operator, %s, is invalid.  Valid operators are AND, OR, and XOR."<\/span>$/;"	a
+l00041	docs/html/psCompare_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="group__Compare.html#ga1">00041<\/a> <span class="keyword">typedef<\/span> int (*<a class="code" href="group__Compare.html#ga1">psCompareFcn<\/a>) ($/;"	a
+l00041	docs/html/psCoord_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsPlane.html#o1">00041<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> y;                   <span class="comment">\/\/\/&lt; y position<\/span>$/;"	a
+l00041	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="psDataManipErrors_8h.html#a10">00041<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET "Must specify the direction as either PS_FFT_FORWARD or PS_FFT_REVERSE."<\/span>$/;"	a
+l00041	docs/html/psHash_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsHash.html#o0">00041<\/a>     <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structpsHash.html#o0">nbucket<\/a>;                <span class="comment">\/\/\/&lt; Number of buckets in hash table.<\/span>$/;"	a
+l00041	docs/html/psImageErrors_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="psImageErrors_8h.html#a10">00041<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_NOT_PARENT "Specified psImage can not be a child of another psImage."<\/span>$/;"	a
+l00041	docs/html/psList_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsListElem.html#o1">00041<\/a> <span class="comment"><\/span>    <span class="keyword">struct <\/span><a class="code" href="structpsListElem.html">psListElem<\/a>* <a class="code" href="structpsListElem.html#o1">next<\/a>;           <span class="comment">\/\/\/&lt; next link in list<\/span>$/;"	a
+l00041	docs/html/psMinimize_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsMinimization.html#o0">00041<\/a>     <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> maxIter;                       <span class="comment">\/\/\/&lt; Convergence limit<\/span>$/;"	a
+l00041	docs/html/psRandom_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsRandom.html#o0">00041<\/a>     <a class="code" href="group__Math.html#ga5">psRandomType<\/a> type; <span class="comment">\/\/\/&lt; The type of RNG<\/span>$/;"	a
+l00041	docs/html/psScalar_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsScalar.html#o5">00041<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga4">psS8<\/a> S8;                <span class="comment">\/\/\/&lt; Signed 8-bit integer data.<\/span>$/;"	a
+l00041	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a10">00041<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMemory_MULTIPLE_FREE "Block %lld, allocated at %s:%d, freed multiple times at %s:%d."<\/span>$/;"	a
+l00041	docs/html/psVector_8h-source.html	/^<a name="l00041"><\/a><a class="code" href="structpsVector.html#o5">00041<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga2">psU32<\/a>* U32;             <span class="comment">\/\/\/&lt; Unsigned 32-bit integer data.<\/span>$/;"	a
+l00042	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="psAstronomyErrors_8h.html#a11">00042<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_GET_TOD_FAILED "Failed to determine the current time from gettimeofday function."<\/span>$/;"	a
+l00042	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="psCollectionsErrors_8h.html#a11">00042<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL "First psBitSet operand can not be NULL."<\/span>$/;"	a
+l00042	docs/html/psCoord_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsPlane.html#o2">00042<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> xErr;                <span class="comment">\/\/\/&lt; Error in x position<\/span>$/;"	a
+l00042	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="psDataManipErrors_8h.html#a11">00042<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_NOT_F32_F64 "Invalid data type, %s.  Only psF32 and psF64 data types are supported."<\/span>$/;"	a
+l00042	docs/html/psHash_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsHash.html#o1">00042<\/a> <span class="comment"><\/span>    <a class="code" href="structpsHashBucket.html">psHashBucket<\/a>* *<a class="code" href="structpsHash.html#o1">buckets<\/a>;     <span class="comment">\/\/\/&lt; The bucket data.<\/span>$/;"	a
+l00042	docs/html/psImageErrors_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="psImageErrors_8h.html#a11">00042<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED "Specified input and output psImage can not reference the same psImage."<\/span>$/;"	a
+l00042	docs/html/psList_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsListElem.html#o2">00042<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsListElem.html#o2">data<\/a>;                        <span class="comment">\/\/\/&lt; real data item<\/span>$/;"	a
+l00042	docs/html/psMinimize_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsMinimization.html#o1">00042<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> tol;                         <span class="comment">\/\/\/&lt; Error Tolerance<\/span>$/;"	a
+l00042	docs/html/psRandom_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsRandom.html#o1">00042<\/a> <span class="comment"><\/span>    gsl_rng *gsl; <span class="comment">\/\/\/&lt; The RNG itself<\/span>$/;"	a
+l00042	docs/html/psScalar_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsScalar.html#o6">00042<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga5">psS16<\/a> S16;              <span class="comment">\/\/\/&lt; Signed 16-bit integer data.<\/span>$/;"	a
+l00042	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a11">00042<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psString_NCHAR_NEGATIVE "Can not copy a negative number of characters (%d)."<\/span>$/;"	a
+l00042	docs/html/psVector_8h-source.html	/^<a name="l00042"><\/a><a class="code" href="structpsVector.html#o6">00042<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga3">psU64<\/a>* U64;             <span class="comment">\/\/\/&lt; Unsigned 64-bit integer data.<\/span>$/;"	a
+l00043	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="psAstronomyErrors_8h.html#a12">00043<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED "Failed to convert a time via strftime function."<\/span>$/;"	a
+l00043	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="psCollectionsErrors_8h.html#a12">00043<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL "Second psBitSet operand can not be NULL."<\/span>$/;"	a
+l00043	docs/html/psCoord_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="structpsPlane.html#o3">00043<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> yErr;                <span class="comment">\/\/\/&lt; Error in y position<\/span>$/;"	a
+l00043	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="psDataManipErrors_8h.html#a12">00043<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_VECTOR_TYPE_UNSUPPORTED "Input psVector type, %s, is not supported."<\/span>$/;"	a
+l00043	docs/html/psImageErrors_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="psImageErrors_8h.html#a12">00043<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_SUBSET_ZERO_SIZE "Specified subset, [%d:%d,%d:%d], contains no pixel data."<\/span>$/;"	a
+l00043	docs/html/psMinimize_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="structpsMinimization.html#o2">00043<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> value;                       <span class="comment">\/\/\/&lt; Value of function at minimum<\/span>$/;"	a
+l00043	docs/html/psPhotometry_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="structpsPhotSystem.html">00043<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00043	docs/html/psScalar_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="structpsScalar.html#o7">00043<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> S32;              <span class="comment">\/\/\/&lt; Signed 32-bit integer data.<\/span>$/;"	a
+l00043	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a12">00043<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT "Sub-component %d of node %s in trace tree is NULL."<\/span>$/;"	a
+l00043	docs/html/psType_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="group__DataContainer.html#ga0">00043<\/a> <span class="keyword">typedef<\/span> uint8_t <a class="code" href="group__DataContainer.html#ga0">psU8<\/a>;                  <span class="comment">\/\/\/&lt; 8-bit unsigned int<\/span>$/;"	a
+l00043	docs/html/psVector_8h-source.html	/^<a name="l00043"><\/a><a class="code" href="structpsVector.html#o7">00043<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga4">psS8<\/a>* S8;               <span class="comment">\/\/\/&lt; Signed 8-bit integer data.<\/span>$/;"	a
+l00044	docs/html/psAstrometry_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="structpsGrommit.html">00044<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00044	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="psAstronomyErrors_8h.html#a13">00044<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED "Failed to append millisecond to time string with snprintf function."<\/span>$/;"	a
+l00044	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="psCollectionsErrors_8h.html#a13">00044<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER "The psBitSet operand must be the same size."<\/span>$/;"	a
+l00044	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="psDataManipErrors_8h.html#a13">00044<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_YVAL_OUT_OF_RANGE "Specified yVal, %g, is not within y-range, %g to %g."<\/span>$/;"	a
+l00044	docs/html/psImageErrors_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="psImageErrors_8h.html#a13">00044<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE "Input psImage mask size, %dx%d, does not match psImage input size, %dx%d."<\/span>$/;"	a
+l00044	docs/html/psMinimize_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="structpsMinimization.html#o3">00044<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> iter;                          <span class="comment">\/\/\/&lt; Number of iterations required<\/span>$/;"	a
+l00044	docs/html/psScalar_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="structpsScalar.html#o8">00044<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga7">psS64<\/a> S64;              <span class="comment">\/\/\/&lt; Signed 64-bit integer data.<\/span>$/;"	a
+l00044	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a13">00044<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTrace_NULL_TRACETREE "Function %s called on a NULL trace level tree."<\/span>$/;"	a
+l00044	docs/html/psType_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="group__DataContainer.html#ga1">00044<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> uint16_t <a class="code" href="group__DataContainer.html#ga1">psU16<\/a>;                <span class="comment">\/\/\/&lt; 16-bit unsigned int<\/span>$/;"	a
+l00044	docs/html/psVector_8h-source.html	/^<a name="l00044"><\/a><a class="code" href="structpsVector.html#o8">00044<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga5">psS16<\/a>* S16;             <span class="comment">\/\/\/&lt; Signed 16-bit integer data.<\/span>$/;"	a
+l00045	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="psAstronomyErrors_8h.html#a14">00045<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_USEC_INVALID "The psTime usec attribute value, %u, is invalid.  Must be less than 1e6."<\/span>$/;"	a
+l00045	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="psCollectionsErrors_8h.html#a14">00045<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_NOT_OP_FAILED "Could not perform NOT operation."<\/span>$/;"	a
+l00045	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="psDataManipErrors_8h.html#a14">00045<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_ROBUST_QUARTILE_BINS_FAILED "Could not determine the robust lower\/upper quartile bin numbers."<\/span>$/;"	a
+l00045	docs/html/psImageErrors_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="psImageErrors_8h.html#a14">00045<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE "Input psImage mask type, %s, is not the supported mask datatype of %s."<\/span>$/;"	a
+l00045	docs/html/psMinimize_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="structpsMinimization.html#o4">00045<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> lastDelta;                   <span class="comment">\/\/\/&lt; The last difference for the fit<\/span>$/;"	a
+l00045	docs/html/psPhotometry_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="structpsPhotSystem.html#o0">00045<\/a>     <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> ID;               <span class="comment">\/\/\/&lt; ID number for this photometric system<\/span>$/;"	a
+l00045	docs/html/psScalar_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="structpsScalar.html#o9">00045<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga8">psF32<\/a> F32;              <span class="comment">\/\/\/&lt; Single-precision float data.<\/span>$/;"	a
+l00045	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a14">00045<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT "Failed to add null component to trace tree."<\/span>$/;"	a
+l00045	docs/html/psType_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="group__DataContainer.html#ga2">00045<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> uint32_t <a class="code" href="group__DataContainer.html#ga2">psU32<\/a>;                <span class="comment">\/\/\/&lt; 32-bit unsigned int<\/span>$/;"	a
+l00045	docs/html/psVector_8h-source.html	/^<a name="l00045"><\/a><a class="code" href="structpsVector.html#o9">00045<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga6">psS32<\/a>* S32;             <span class="comment">\/\/\/&lt; Signed 32-bit integer data.<\/span>$/;"	a
+l00046	docs/html/psAstrometry_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="structpsGrommit.html#o0">00046<\/a>     <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> latitude;             <span class="comment">\/\/\/&lt; geodetic latitude (radians)<\/span>$/;"	a
+l00046	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psAstronomyErrors_8h.html#a15">00046<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_ISOTIME_MALFORMED "Specified ISO Time string, '%s', is malformed.  Must be in 'YYYY-MM-DDThh:mm:ss.sss' format."<\/span>$/;"	a
+l00046	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psCollectionsErrors_8h.html#a15">00046<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psBitSet_OPERAND_NULL "Operand can not be NULL."<\/span>$/;"	a
+l00046	docs/html/psConstants_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psConstants_8h.html#a8">00046<\/a> <span class="preprocessor">#define PS_INT_CHECK_POSITIVE(NAME, RVAL) \\<\/span>$/;"	a
+l00046	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psDataManipErrors_8h.html#a15">00046<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_FAILED "Failed to calculate the specified statistic."<\/span>$/;"	a
+l00046	docs/html/psImageErrors_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psImageErrors_8h.html#a15">00046<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_BAD_STAT "Specified statistic option, %d, is not valid.  Must specify one and only one statistic type."<\/span>$/;"	a
+l00046	docs/html/psImage_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="structpsImage.html">00046<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsImage.html">psImage<\/a>$/;"	a
+l00046	docs/html/psPhotometry_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="structpsPhotSystem.html#o1">00046<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *name;           <span class="comment">\/\/\/&lt; Name of photometric system<\/span>$/;"	a
+l00046	docs/html/psScalar_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="structpsScalar.html#o10">00046<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga9">psF64<\/a> F64;              <span class="comment">\/\/\/&lt; Double-precision float data.<\/span>$/;"	a
+l00046	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a15">00046<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME "Failed to add '%s' to the root component tree; component must start with '.'."<\/span>$/;"	a
+l00046	docs/html/psType_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="group__DataContainer.html#ga3">00046<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> uint64_t <a class="code" href="group__DataContainer.html#ga3">psU64<\/a>;                <span class="comment">\/\/\/&lt; 64-bit unsigned int<\/span>$/;"	a
+l00046	docs/html/psVector_8h-source.html	/^<a name="l00046"><\/a><a class="code" href="structpsVector.html#o10">00046<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga7">psS64<\/a>* S64;             <span class="comment">\/\/\/&lt; Signed 64-bit integer data.<\/span>$/;"	a
+l00047	docs/html/psAstrometry_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="structpsGrommit.html#o1">00047<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> sinLat;               <span class="comment">\/\/\/&lt; sine of geodetic latitude<\/span>$/;"	a
+l00047	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="psAstronomyErrors_8h.html#a16">00047<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED "Failed time table interpolation."<\/span>$/;"	a
+l00047	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="psCollectionsErrors_8h.html#a16">00047<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE "Specified datatype (%d) is unsupported by psScalar."<\/span>$/;"	a
+l00047	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="psDataManipErrors_8h.html#a16">00047<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_SAMPLE_MEDIAN_SORT_PROBLEM "Failed to sort input data."<\/span>$/;"	a
+l00047	docs/html/psImageErrors_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="psImageErrors_8h.html#a16">00047<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_NO_STAT_OPTIONS "Specified statistic option did not indicate any operation to perform."<\/span>$/;"	a
+l00047	docs/html/psPhotometry_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="structpsPhotSystem.html#o2">00047<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *camera;         <span class="comment">\/\/\/&lt; Camera for photometric system<\/span>$/;"	a
+l00047	docs/html/psScalar_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="structpsScalar.html#o11">00047<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga10">psC32<\/a> C32;              <span class="comment">\/\/\/&lt; Single-precision complex data.<\/span>$/;"	a
+l00047	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a16">00047<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT "Failed to set trace level (%d) to '%s'."<\/span>$/;"	a
+l00047	docs/html/psType_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="group__DataContainer.html#ga4">00047<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> int8_t <a class="code" href="group__DataContainer.html#ga4">psS8<\/a>;                   <span class="comment">\/\/\/&lt; 8-bit signed int<\/span>$/;"	a
+l00047	docs/html/psVector_8h-source.html	/^<a name="l00047"><\/a><a class="code" href="structpsVector.html#o11">00047<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga8">psF32<\/a>* F32;             <span class="comment">\/\/\/&lt; Single-precision float data.<\/span>$/;"	a
+l00048	docs/html/psAstrometry_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="structpsGrommit.html#o2">00048<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> cosLat;               <span class="comment">\/\/\/&lt; cosine of geodetic latitude<\/span>$/;"	a
+l00048	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="psAstronomyErrors_8h.html#a17">00048<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_INTERPOLATION_FAILED_NAME "Failed time table interpolation for '%s'."<\/span>$/;"	a
+l00048	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="psCollectionsErrors_8h.html#a17">00048<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psScalar_COPY_NULL "Can not copy a NULL psScalar."<\/span>$/;"	a
+l00048	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="psDataManipErrors_8h.html#a17">00048<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_VECTOR_BIN_DISECT_PROBLEM "Failed to determine the bin number of a data element."<\/span>$/;"	a
+l00048	docs/html/psImageErrors_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="psImageErrors_8h.html#a17">00048<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_STAT_NULL "Specified statistic can not be NULL."<\/span>$/;"	a
+l00048	docs/html/psImage_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="structpsImage.html#o0">00048<\/a>     <span class="keyword">const<\/span> <a class="code" href="structpsType.html">psType<\/a> <a class="code" href="structpsImage.html#o0">type<\/a>;                 <span class="comment">\/\/\/&lt; Image data type and dimension.<\/span>$/;"	a
+l00048	docs/html/psPhotometry_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="structpsPhotSystem.html#o3">00048<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *filter;         <span class="comment">\/\/\/&lt; Filter used for photometric system<\/span>$/;"	a
+l00048	docs/html/psScalar_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="structpsScalar.html#o12">00048<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga11">psC64<\/a> C64;              <span class="comment">\/\/\/&lt; Double-precision complex data.<\/span>$/;"	a
+l00048	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a17">00048<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION "Specified psErrorDescription pointer can not be NULL."<\/span>$/;"	a
+l00048	docs/html/psType_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="group__DataContainer.html#ga5">00048<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> int16_t <a class="code" href="group__DataContainer.html#ga5">psS16<\/a>;                 <span class="comment">\/\/\/&lt; 16-bit signed int<\/span>$/;"	a
+l00048	docs/html/psVector_8h-source.html	/^<a name="l00048"><\/a><a class="code" href="structpsVector.html#o12">00048<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga9">psF64<\/a>* F64;             <span class="comment">\/\/\/&lt; Double-precision float data.<\/span>$/;"	a
+l00049	docs/html/psAstrometry_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="structpsGrommit.html#o3">00049<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> abberationMag;        <span class="comment">\/\/\/&lt; magnitude of diurnal aberration vector<\/span>$/;"	a
+l00049	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="psAstronomyErrors_8h.html#a18">00049<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_LOOKUP_METADATA_FAILED "Failed find '%s' in time metadata."<\/span>$/;"	a
+l00049	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="psCollectionsErrors_8h.html#a18">00049<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psHash_KEY_NULL "Input key can not be NULL."<\/span>$/;"	a
+l00049	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="psDataManipErrors_8h.html#a18">00049<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLYNOMIAL_1D_FIT "Failed to fit a 1-dimensional polynomial to the three specified data points.  Returning NAN."<\/span>$/;"	a
+l00049	docs/html/psImageErrors_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="psImageErrors_8h.html#a18">00049<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID "Specified slice direction, %d, is invalid."<\/span>$/;"	a
+l00049	docs/html/psImage_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="structpsImage.html#o1">00049<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> <a class="code" href="structpsImage.html#o1">numCols<\/a>;        <span class="comment">\/\/\/&lt; Number of columns in image<\/span>$/;"	a
+l00049	docs/html/psPhotometry_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="structpsPhotSystem.html#o4">00049<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *detector;       <span class="comment">\/\/\/&lt; Detector used for photometric system<\/span>$/;"	a
+l00049	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a18">00049<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED "Failed to add input psErrorDescription at array index %d."<\/span>$/;"	a
+l00049	docs/html/psType_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="group__DataContainer.html#ga6">00049<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> int32_t <a class="code" href="group__DataContainer.html#ga6">psS32<\/a>;                 <span class="comment">\/\/\/&lt; 32-bit signed int<\/span>$/;"	a
+l00049	docs/html/psVector_8h-source.html	/^<a name="l00049"><\/a><a class="code" href="structpsVector.html#o13">00049<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga10">psC32<\/a>* C32;             <span class="comment">\/\/\/&lt; Single-precision complex data.<\/span>$/;"	a
+l00050	docs/html/psAstrometry_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="structpsGrommit.html#o4">00050<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> height;               <span class="comment">\/\/\/&lt; height (HM)<\/span>$/;"	a
+l00050	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="psAstronomyErrors_8h.html#a19">00050<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_BAD_TABLE_COUNT "Incorrect number of table files entered. Found: %d. Expected: %d."<\/span>$/;"	a
+l00050	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="psCollectionsErrors_8h.html#a19">00050<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psHash_TABLE_NULL "Input psHash can not be NULL."<\/span>$/;"	a
+l00050	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="psDataManipErrors_8h.html#a19">00050<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_FIT_QUADRATIC_POLY_MEDIAN "Failed to determine the median of the fitted polynomial.  Returning NAN."<\/span>$/;"	a
+l00050	docs/html/psImageErrors_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="psImageErrors_8h.html#a19">00050<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE "Specified %s value, %g, is outside of psImage type's range (%s: %g to %g)."<\/span>$/;"	a
+l00050	docs/html/psImage_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="structpsImage.html#o2">00050<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> <a class="code" href="structpsImage.html#o2">numRows<\/a>;        <span class="comment">\/\/\/&lt; Number of rows in image.<\/span>$/;"	a
+l00050	docs/html/psList_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="structpsList.html">00050<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span>{$/;"	a
+l00050	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a19">00050<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psConfigure_INITIALIZATION_FAILED "Failed to initialize %s."<\/span>$/;"	a
+l00050	docs/html/psTrace_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="structp__psComponent.html">00050<\/a>     <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structp__psComponent.html">p_psComponent<\/a>$/;"	a
+l00050	docs/html/psType_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="group__DataContainer.html#ga7">00050<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> int64_t <a class="code" href="group__DataContainer.html#ga7">psS64<\/a>;                 <span class="comment">\/\/\/&lt; 64-bit signed int<\/span>$/;"	a
+l00050	docs/html/psVector_8h-source.html	/^<a name="l00050"><\/a><a class="code" href="structpsVector.html#o14">00050<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga11">psC64<\/a>* C64;             <span class="comment">\/\/\/&lt; Double-precision complex data.<\/span>$/;"	a
+l00051	docs/html/psAstrometry_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="structpsGrommit.html#o5">00051<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> temperature;          <span class="comment">\/\/\/&lt; ambient temperature (TDK)<\/span>$/;"	a
+l00051	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="psAstronomyErrors_8h.html#a20">00051<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psTime_BAD_VECTOR "Incorrect vector size. Size: %d, Expected %d."<\/span>$/;"	a
+l00051	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="psCollectionsErrors_8h.html#a20">00051<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psHash_DATA_NULL "Input data can not be NULL."<\/span>$/;"	a
+l00051	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="psDataManipErrors_8h.html#a20">00051<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_ROBUST_STATS_CLIPPED_STATS "Failed to determine clipped statistics."<\/span>$/;"	a
+l00051	docs/html/psImageErrors_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="psImageErrors_8h.html#a20">00051<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_nSamples_TOOSMALL "Specified number of samples, %d, must be greater than 1 to make a line."<\/span>$/;"	a
+l00051	docs/html/psImage_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="structpsImage.html#o3">00051<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structpsImage.html#o3">col0<\/a>;                    <span class="comment">\/\/\/&lt; Column position relative to parent.<\/span>$/;"	a
+l00051	docs/html/psList_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="structpsList.html#o0">00051<\/a>     <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> size;                        <span class="comment">\/\/\/&lt; number of elements on list<\/span>$/;"	a
+l00051	docs/html/psMemory_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="group__MemoryManagement.html#ga0">00051<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <a class="code" href="group__DataContainer.html#ga3">psU64<\/a> <a class="code" href="group__MemoryManagement.html#ga0">psMemoryId<\/a>;$/;"	a
+l00051	docs/html/psSysUtilsErrors_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="psSysUtilsErrors_8h.html#a20">00051<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psConfigure_FINALIZATION_FAILED "Failed to finalize %s."<\/span>$/;"	a
+l00051	docs/html/psType_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="group__DataContainer.html#ga8">00051<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">float<\/span> <a class="code" href="group__DataContainer.html#ga8">psF32<\/a>;                   <span class="comment">\/\/\/&lt; 32-bit floating point<\/span>$/;"	a
+l00051	docs/html/psVector_8h-source.html	/^<a name="l00051"><\/a><a class="code" href="structpsVector.html#o15">00051<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> V;                <span class="comment">\/\/\/&lt; Pointer to data.<\/span>$/;"	a
+l00052	docs/html/psAstrometry_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="structpsGrommit.html#o6">00052<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> pressure;             <span class="comment">\/\/\/&lt; pressure (PMB)<\/span>$/;"	a
+l00052	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="psAstronomyErrors_8h.html#a21">00052<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNDEFINED "The projection type, %s, is undefined."<\/span>$/;"	a
+l00052	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="psCollectionsErrors_8h.html#a21">00052<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_LOCATION_INVALID "Specified location, %d, is invalid."<\/span>$/;"	a
+l00052	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="psDataManipErrors_8h.html#a21">00052<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psStats_STATS_POLY_MEDIAN_OUT_OF_RANGE "The requested y-value does not fall with the specified range of x-values.  Returning NAN."<\/span>$/;"	a
+l00052	docs/html/psImageErrors_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="psImageErrors_8h.html#a21">00052<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE "Specified line, (%f,%f)-&gt;(%f,%f), does not entirely lie in psImage's boundaries, [0:%d,0:%d]."<\/span>$/;"	a
+l00052	docs/html/psImage_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="structpsImage.html#o4">00052<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structpsImage.html#o4">row0<\/a>;                    <span class="comment">\/\/\/&lt; Row position relative to parent.<\/span>$/;"	a
+l00052	docs/html/psList_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="structpsList.html#o1">00052<\/a> <span class="comment"><\/span>    <a class="code" href="structpsListElem.html">psListElem<\/a>* head;                  <span class="comment">\/\/\/&lt; first element on list (may be NULL)<\/span>$/;"	a
+l00052	docs/html/psTrace_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="structp__psComponent.html#o0">00052<\/a>         <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *<a class="code" href="structp__psComponent.html#o0">name<\/a>;           <span class="comment">\/\/ last part of name of component<\/span>$/;"	a
+l00052	docs/html/psType_8h-source.html	/^<a name="l00052"><\/a><a class="code" href="group__DataContainer.html#ga9">00052<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">double<\/span> <a class="code" href="group__DataContainer.html#ga9">psF64<\/a>;                  <span class="comment">\/\/\/&lt; 64-bit floating point<\/span>$/;"	a
+l00053	docs/html/psAstrometry_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="structpsGrommit.html#o7">00053<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> humidity;             <span class="comment">\/\/\/&lt; relative humidity (RH)<\/span>$/;"	a
+l00053	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="psAstronomyErrors_8h.html#a22">00053<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psCoord_PROJECTION_TYPE_UNKNOWN "The projection type, %d, is unknown."<\/span>$/;"	a
+l00053	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="psCollectionsErrors_8h.html#a22">00053<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_ITERATOR_INVALID "Specified iterator is not valid."<\/span>$/;"	a
+l00053	docs/html/psConstants_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="psConstants_8h.html#a9">00053<\/a> <span class="preprocessor">#define PS_INT_CHECK_ZERO(NAME, RVAL) \\<\/span>$/;"	a
+l00053	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="psDataManipErrors_8h.html#a22">00053<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psFunctions_INVALID_POLYNOMIAL_TYPE "Unknown polynomial type 0x%x found.  Evaluation failed."<\/span>$/;"	a
+l00053	docs/html/psImageErrors_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="psImageErrors_8h.html#a22">00053<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_RADII_VECTOR_NULL "Specified radii vector can not be NULL."<\/span>$/;"	a
+l00053	docs/html/psList_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="structpsList.html#o2">00053<\/a> <span class="comment"><\/span>    <a class="code" href="structpsListElem.html">psListElem<\/a>* tail;                  <span class="comment">\/\/\/&lt; last element on list (may be NULL)<\/span>$/;"	a
+l00053	docs/html/psTrace_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="structp__psComponent.html#o1">00053<\/a>         <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structp__psComponent.html#o1">level<\/a>;                  <span class="comment">\/\/ trace level for this component<\/span>$/;"	a
+l00053	docs/html/psType_8h-source.html	/^<a name="l00053"><\/a><a class="code" href="group__DataContainer.html#ga10">00053<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">float<\/span> _Complex <a class="code" href="group__DataContainer.html#ga10">psC32<\/a>;          <span class="comment">\/\/\/&lt; complex with 32-bit floating point Real and Imagary numbers<\/span>$/;"	a
+l00054	docs/html/psAstrometry_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="structpsGrommit.html#o8">00054<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> wavelength;           <span class="comment">\/\/\/&lt; wavelength (WL)<\/span>$/;"	a
+l00054	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="psAstronomyErrors_8h.html#a23">00054<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psCoord_UNITS_UNKNOWN "Specified units, 0x%x, is not supported."<\/span>$/;"	a
+l00054	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="psCollectionsErrors_8h.html#a23">00054<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_ITERATOR_NULL "Specified iterator is NULL."<\/span>$/;"	a
+l00054	docs/html/psCoord_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="structpsSphere.html">00054<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsSphere.html">psSphere<\/a>$/;"	a
+l00054	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="psDataManipErrors_8h.html#a23">00054<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psFunctions_TYPE_NOT_SUPPORTED "Input psVector type, %s, is not supported."<\/span>$/;"	a
+l00054	docs/html/psImageErrors_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="psImageErrors_8h.html#a23">00054<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE "Specified center, (%g,%g), is outside of the psImage boundaries, [0:%d,0:%d]."<\/span>$/;"	a
+l00054	docs/html/psMemory_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="group__MemoryManagement.html#ga1">00054<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <a class="code" href="group__DataContainer.html#ga3">psU64<\/a> <a class="code" href="group__MemoryManagement.html#ga1">psReferenceCount<\/a>;$/;"	a
+l00054	docs/html/psTrace_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="structp__psComponent.html#o2">00054<\/a>         <span class="keywordtype">bool<\/span> <a class="code" href="structp__psComponent.html#o2">p_psSpecified<\/a>;$/;"	a
+l00054	docs/html/psType_8h-source.html	/^<a name="l00054"><\/a><a class="code" href="group__DataContainer.html#ga11">00054<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">double<\/span> _Complex <a class="code" href="group__DataContainer.html#ga11">psC64<\/a>;         <span class="comment">\/\/\/&lt; complex with 64-bit floating point Real and Imagary numbers<\/span>$/;"	a
+l00055	docs/html/psAstrometry_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="structpsGrommit.html#o9">00055<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> lapseRate;            <span class="comment">\/\/\/&lt; lapse rate (TLR)<\/span>$/;"	a
+l00055	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="psAstronomyErrors_8h.html#a24">00055<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psCoord_OFFSET_MODE_UNKNOWN "Specified offset mode, 0x%x, is not supported."<\/span>$/;"	a
+l00055	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="psCollectionsErrors_8h.html#a24">00055<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_LIST_NULL "Specified psList reference is NULL. "<\/span>$/;"	a
+l00055	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="psDataManipErrors_8h.html#a24">00055<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psFunctions_NOT_ENOUGH_DATAPOINTS "Given vector does not have enough data points for %d-order interpolation."<\/span>$/;"	a
+l00055	docs/html/psImageErrors_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="psImageErrors_8h.html#a24">00055<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL "Input radii vector size, %d, can not be less than 2."<\/span>$/;"	a
+l00055	docs/html/psImage_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="structpsImage.html#o5">00055<\/a>         <a class="code" href="group__DataContainer.html#ga0">psU8<\/a>**  <a class="code" href="structpsImage.html#o5">U8<\/a>;                    <span class="comment">\/\/\/&lt; Unsigned 8-bit integer data.<\/span>$/;"	a
+l00055	docs/html/psList_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="structpsList.html#o3">00055<\/a> <span class="comment">    \/\/\/&lt; array of all iterators associated with this list.  First iterator is <\/span>$/;"	a
+l00055	docs/html/psTrace_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="structp__psComponent.html#o3">00055<\/a>         <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structp__psComponent.html#o3">n<\/a>;                      <span class="comment">\/\/ number of subcomponents<\/span>$/;"	a
+l00055	docs/html/psType_8h-source.html	/^<a name="l00055"><\/a><a class="code" href="group__DataContainer.html#ga12">00055<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">void<\/span>* <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a>;                   <span class="comment">\/\/\/&lt; void pointer<\/span>$/;"	a
+l00056	docs/html/psAstrometry_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structpsGrommit.html#o10">00056<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> refractA;             <span class="comment">\/\/\/&lt; refraction constant A (radians)<\/span>$/;"	a
+l00056	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="psAstronomyErrors_8h.html#a25">00056<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psAstrometry_NONLINEAR_TRANSFORM "The %s transfrom is not linear.  Only linear transforms are supported."<\/span>$/;"	a
+l00056	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="psCollectionsErrors_8h.html#a25">00056<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_DATA_NULL "Specified data item is NULL."<\/span>$/;"	a
+l00056	docs/html/psCoord_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structpsSphere.html#o0">00056<\/a>     <span class="keywordtype">double<\/span> <a class="code" href="structpsSphere.html#o0">r<\/a>;                   <span class="comment">\/\/\/&lt; RA<\/span>$/;"	a
+l00056	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="psDataManipErrors_8h.html#a25">00056<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psRandom_UNKNOWN_RANDFOM_NUMBER_GENERATOR_TYPE "Unknown Random Number Generator Type"<\/span>$/;"	a
+l00056	docs/html/psImageErrors_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="psImageErrors_8h.html#a25">00056<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_IMAGE_TYPE_UNSUPPORTED "Input psImage type (%s) is not supported. Valid image types are psF32 and psC32."<\/span>$/;"	a
+l00056	docs/html/psImage_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structpsImage.html#o6">00056<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga1">psU16<\/a>** <a class="code" href="structpsImage.html#o6">U16<\/a>;                   <span class="comment">\/\/\/&lt; Unsigned 16-bit integer data.<\/span>$/;"	a
+l00056	docs/html/psMetadata_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structpsMetadata.html">00056<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsMetadata.html">psMetadata<\/a>$/;"	a
+l00056	docs/html/psStats_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structpsStats.html">00056<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00056	docs/html/psTrace_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="structp__psComponent.html#o4">00056<\/a>         <span class="keyword">struct <\/span><a class="code" href="structp__psComponent.html">p_psComponent<\/a>* *<a class="code" href="structp__psComponent.html#o4">subcomp<\/a>;     <span class="comment">\/\/ next level of subcomponents<\/span>$/;"	a
+l00056	docs/html/psType_8h-source.html	/^<a name="l00056"><\/a><a class="code" href="group__DataContainer.html#ga13">00056<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> <span class="keywordtype">bool<\/span> <a class="code" href="group__DataContainer.html#ga13">psBool<\/a>;                   <span class="comment">\/\/\/&lt; boolean value<\/span>$/;"	a
+l00057	docs/html/psAstrometry_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="structpsGrommit.html#o11">00057<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> refractB;             <span class="comment">\/\/\/&lt; refraction constant B (radians)<\/span>$/;"	a
+l00057	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="psAstronomyErrors_8h.html#a26">00057<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_METATYPE_INVALID "Specified psMetadataType, %d, is not supported."<\/span>$/;"	a
+l00057	docs/html/psCollectionsErrors_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="psCollectionsErrors_8h.html#a26">00057<\/a> <span class="preprocessor"><\/span><span class="preprocessor"> #define PS_ERRORTEXT_psList_DATA_NOT_FOUND "Specified data item is not found in the psList."<\/span>$/;"	a
+l00057	docs/html/psCoord_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="structpsSphere.html#o1">00057<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> <a class="code" href="structpsSphere.html#o1">d<\/a>;                   <span class="comment">\/\/\/&lt; Dec<\/span>$/;"	a
+l00057	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="psDataManipErrors_8h.html#a26">00057<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_COUNT_DIFFERS "Number of elements inconsistent, %d vs %d.  Number of elements must match."<\/span>$/;"	a
+l00057	docs/html/psImageErrors_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="psImageErrors_8h.html#a26">00057<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_REVERSE_NOT_COMPLEX "Input psImage (%s) is not complex.  Reverse FFT operation requires a complex psImage input."<\/span>$/;"	a
+l00057	docs/html/psImage_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="structpsImage.html#o7">00057<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga2">psU32<\/a>** <a class="code" href="structpsImage.html#o7">U32<\/a>;                   <span class="comment">\/\/\/&lt; Unsigned 32-bit integer data.<\/span>$/;"	a
+l00057	docs/html/psMemory_8h-source.html	/^<a name="l00057"><\/a><a class="code" href="group__MemoryManagement.html#ga2">00057<\/a> <span class="comment"><\/span><span class="keyword">typedef<\/span> void (*<a class="code" href="group__MemoryManagement.html#ga2">psFreeFcn<\/a>) (<a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> ptr);$/;"	a
+l00058	docs/html/psAstrometry_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="structpsGrommit.html#o12">00058<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> longitudeOffset;      <span class="comment">\/\/\/&lt; longitude + ... (radians)<\/span>$/;"	a
+l00058	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="psAstronomyErrors_8h.html#a27">00058<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_METATYPE_MISMATCH "Specified psMetadataType, %d, is incorrect. Expected %d."<\/span>$/;"	a
+l00058	docs/html/psCoord_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="structpsSphere.html#o2">00058<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> <a class="code" href="structpsSphere.html#o2">rErr<\/a>;                <span class="comment">\/\/\/&lt; Error in RA<\/span>$/;"	a
+l00058	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="psDataManipErrors_8h.html#a27">00058<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_IMAGE_SIZE_DIFFERS "Specified psImage dimensions differed, %dx%d vs %dx%d."<\/span>$/;"	a
+l00058	docs/html/psImageErrors_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="psImageErrors_8h.html#a27">00058<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_FORWARD_NOT_REAL "Input psImage (%s) is not real.  Forward FFT operation requires a real psImage input."<\/span>$/;"	a
+l00058	docs/html/psImage_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="structpsImage.html#o8">00058<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga3">psU64<\/a>** <a class="code" href="structpsImage.html#o8">U64<\/a>;                   <span class="comment">\/\/\/&lt; Unsigned 64-bit integer data.<\/span>$/;"	a
+l00058	docs/html/psMetadata_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="structpsMetadata.html#o0">00058<\/a>     <a class="code" href="structpsList.html">psList<\/a>*  <a class="code" href="structpsMetadata.html#o0">list<\/a>;                     <span class="comment">\/\/\/&lt; Metadata in linked-list<\/span>$/;"	a
+l00058	docs/html/psStats_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="structpsStats.html#o0">00058<\/a>     <span class="keywordtype">double<\/span> sampleMean;          <span class="comment">\/\/\/&lt; formal mean of sample<\/span>$/;"	a
+l00058	docs/html/psType_8h-source.html	/^<a name="l00058"><\/a><a class="code" href="group__DataContainer.html#ga67">00058<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00059	docs/html/psAstrometry_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsGrommit.html#o13">00059<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> siderealTime;         <span class="comment">\/\/\/&lt; local apparent sidereal time (radians)<\/span>$/;"	a
+l00059	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="psAstronomyErrors_8h.html#a28">00059<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_ADD_LIST_FAILED "Failed to add metadata item, %s, to items list."<\/span>$/;"	a
+l00059	docs/html/psCoord_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsSphere.html#o3">00059<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> <a class="code" href="structpsSphere.html#o3">dErr<\/a>;                <span class="comment">\/\/\/&lt; Error in Dec<\/span>$/;"	a
+l00059	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="psDataManipErrors_8h.html#a28">00059<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_TYPE_MISMATCH "Specified data type, %s, is not supported."<\/span>$/;"	a
+l00059	docs/html/psImageErrors_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="psImageErrors_8h.html#a28">00059<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL "Could not create a valid FFT plan to perform the transform."<\/span>$/;"	a
+l00059	docs/html/psImage_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsImage.html#o9">00059<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga4">psS8<\/a>**  <a class="code" href="structpsImage.html#o9">S8<\/a>;                    <span class="comment">\/\/\/&lt; Signed 8-bit integer data.<\/span>$/;"	a
+l00059	docs/html/psList_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsList.html#o4">00059<\/a>     pthread_mutex_t lock;              <span class="comment">\/\/\/&lt; mutex to lock a node during changes<\/span>$/;"	a
+l00059	docs/html/psMetadata_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsMetadata.html#o1">00059<\/a> <span class="comment"><\/span>    <a class="code" href="structpsHash.html">psHash<\/a>*  <a class="code" href="structpsMetadata.html#o1">table<\/a>;                    <span class="comment">\/\/\/&lt; Metadata in a hash table<\/span>$/;"	a
+l00059	docs/html/psPhotometry_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsPhotTransform.html">00059<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00059	docs/html/psStats_8h-source.html	/^<a name="l00059"><\/a><a class="code" href="structpsStats.html#o1">00059<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> sampleMedian;        <span class="comment">\/\/\/&lt; formal median of sample<\/span>$/;"	a
+l00060	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="psAstronomyErrors_8h.html#a29">00060<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED "Failed to add metadata item, %s, to items table."<\/span>$/;"	a
+l00060	docs/html/psConstants_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="psConstants_8h.html#a10">00060<\/a> <span class="preprocessor">#define PS_INT_CHECK_RANGE(NAME, LOWER, UPPER, RVAL) \\<\/span>$/;"	a
+l00060	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="psDataManipErrors_8h.html#a29">00060<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_MIN_COMPLEX_SUPPORT "The minimum operation is not supported with complex data."<\/span>$/;"	a
+l00060	docs/html/psImageErrors_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="psImageErrors_8h.html#a29">00060<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH "Real psImage type (%s) and imaginary psImage type (%s) must be the same."<\/span>$/;"	a
+l00060	docs/html/psImage_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="structpsImage.html#o10">00060<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga5">psS16<\/a>** <a class="code" href="structpsImage.html#o10">S16<\/a>;                   <span class="comment">\/\/\/&lt; Signed 16-bit integer data.<\/span>$/;"	a
+l00060	docs/html/psStats_8h-source.html	/^<a name="l00060"><\/a><a class="code" href="structpsStats.html#o2">00060<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> sampleStdev;         <span class="comment">\/\/\/&lt; standard deviation of sample<\/span>$/;"	a
+l00061	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="psAstronomyErrors_8h.html#a30">00061<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED "Failed to remove metadata item, %s, from metadata list."<\/span>$/;"	a
+l00061	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="psDataManipErrors_8h.html#a30">00061<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_MAX_COMPLEX_SUPPORT "The maximum operation is not supported with complex data."<\/span>$/;"	a
+l00061	docs/html/psImageErrors_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="psImageErrors_8h.html#a30">00061<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH "Real psImage size (%dx%d) and imaginary psImage size (%dx%d) must be the same."<\/span>$/;"	a
+l00061	docs/html/psImage_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="structpsImage.html#o11">00061<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga6">psS32<\/a>** <a class="code" href="structpsImage.html#o11">S32<\/a>;                   <span class="comment">\/\/\/&lt; Signed 32-bit integer data.<\/span>$/;"	a
+l00061	docs/html/psPhotometry_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="structpsPhotTransform.html#o0">00061<\/a>     <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> src;           <span class="comment">\/\/\/&lt; Source photometric system<\/span>$/;"	a
+l00061	docs/html/psStats_8h-source.html	/^<a name="l00061"><\/a><a class="code" href="structpsStats.html#o3">00061<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> sampleUQ;            <span class="comment">\/\/\/&lt; upper quartile of sample<\/span>$/;"	a
+l00062	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="psAstronomyErrors_8h.html#a31">00062<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_REMOVE_LIST_INDEX_FAILED "Failed to remove metadata item, at index %d, from metadata list."<\/span>$/;"	a
+l00062	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="psDataManipErrors_8h.html#a31">00062<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_OPERATION_UNSUPPORTED "Specified operation, %s, is not supported."<\/span>$/;"	a
+l00062	docs/html/psErrorCodes_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="structpsErrorDescription.html">00062<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00062	docs/html/psFunctions_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="group__Stats.html#ga60">00062<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00062	docs/html/psImageErrors_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="psImageErrors_8h.html#a31">00062<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED "Input psImage type, %s, is required to be either psF32 or psF64."<\/span>$/;"	a
+l00062	docs/html/psImage_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="structpsImage.html#o12">00062<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga7">psS64<\/a>** <a class="code" href="structpsImage.html#o12">S64<\/a>;                   <span class="comment">\/\/\/&lt; Signed 64-bit integer data.<\/span>$/;"	a
+l00062	docs/html/psPhotometry_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="structpsPhotTransform.html#o1">00062<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> dst;           <span class="comment">\/\/\/&lt; Destination photometric system<\/span>$/;"	a
+l00062	docs/html/psStats_8h-source.html	/^<a name="l00062"><\/a><a class="code" href="structpsStats.html#o4">00062<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> sampleLQ;            <span class="comment">\/\/\/&lt; lower quartile of sample<\/span>$/;"	a
+l00063	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="psAstronomyErrors_8h.html#a32">00063<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED "Failed to remove metadata item, %s, from metadata table."<\/span>$/;"	a
+l00063	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="psDataManipErrors_8h.html#a32">00063<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_DIMEN_OTHER_FOUND "%s's dimensionality is PS_DIMEN_OTHER, which is  not allowed."<\/span>$/;"	a
+l00063	docs/html/psImageErrors_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="psImageErrors_8h.html#a32">00063<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED "Input psImage type, %s, is required to be either psC32 or psC64."<\/span>$/;"	a
+l00063	docs/html/psImage_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="structpsImage.html#o13">00063<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga8">psF32<\/a>** <a class="code" href="structpsImage.html#o13">F32<\/a>;                   <span class="comment">\/\/\/&lt; Single-precision float data.<\/span>$/;"	a
+l00063	docs/html/psPhotometry_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="structpsPhotTransform.html#o2">00063<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> pP;            <span class="comment">\/\/\/&lt; Primary color reference<\/span>$/;"	a
+l00063	docs/html/psStats_8h-source.html	/^<a name="l00063"><\/a><a class="code" href="structpsStats.html#o5">00063<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustMean;          <span class="comment">\/\/\/&lt; robust mean of array<\/span>$/;"	a
+l00064	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="psAstronomyErrors_8h.html#a33">00064<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED "Failed to add metadata item, %s, to metadata collection list."<\/span>$/;"	a
+l00064	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="psDataManipErrors_8h.html#a33">00064<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_OUTPUT_VECTOR_NOT_CREATED "Couldn't create a proper output psVector."<\/span>$/;"	a
+l00064	docs/html/psErrorCodes_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="structpsErrorDescription.html#o0">00064<\/a>     <a class="code" href="group__ErrorHandling.html#ga13">psErrorCode<\/a> code;                  <span class="comment">\/\/\/&lt; An error code<\/span>$/;"	a
+l00064	docs/html/psImageErrors_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="psImageErrors_8h.html#a33">00064<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED "The PS_FFT_FORWARD and PS_FFT_REAL_RESULT combinition is not supported."<\/span>$/;"	a
+l00064	docs/html/psImage_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="structpsImage.html#o14">00064<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga9">psF64<\/a>** <a class="code" href="structpsImage.html#o14">F64<\/a>;                   <span class="comment">\/\/\/&lt; Double-precision float data.<\/span>$/;"	a
+l00064	docs/html/psMemory_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="structpsMemBlock.html">00064<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsMemBlock.html">psMemBlock<\/a>$/;"	a
+l00064	docs/html/psPhotometry_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="structpsPhotTransform.html#o3">00064<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> pM;            <span class="comment">\/\/\/&lt; Primary color reference<\/span>$/;"	a
+l00064	docs/html/psStats_8h-source.html	/^<a name="l00064"><\/a><a class="code" href="structpsStats.html#o6">00064<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustMedian;        <span class="comment">\/\/\/&lt; robust median of array<\/span>$/;"	a
+l00065	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="psAstronomyErrors_8h.html#a34">00065<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_ADD_FAILED "Failed to add metadata item to metadata collection list."<\/span>$/;"	a
+l00065	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="psDataManipErrors_8h.html#a34">00065<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_OUTPUT_IMAGE_NOT_CREATED "Couldn't create a proper output psImage."<\/span>$/;"	a
+l00065	docs/html/psErrorCodes_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="structpsErrorDescription.html#o1">00065<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *description;           <span class="comment">\/\/\/&lt; the associated description<\/span>$/;"	a
+l00065	docs/html/psImageErrors_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="psImageErrors_8h.html#a34">00065<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE "Can not specify both PS_FFT_FORWARD and PS_FFT_REVERSE options."<\/span>$/;"	a
+l00065	docs/html/psImage_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="structpsImage.html#o15">00065<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga10">psC32<\/a>** <a class="code" href="structpsImage.html#o15">C32<\/a>;                   <span class="comment">\/\/\/&lt; Single-precision complex data.<\/span>$/;"	a
+l00065	docs/html/psPhotometry_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="structpsPhotTransform.html#o4">00065<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> sP;            <span class="comment">\/\/\/&lt; Secondary color reference<\/span>$/;"	a
+l00065	docs/html/psStats_8h-source.html	/^<a name="l00065"><\/a><a class="code" href="structpsStats.html#o7">00065<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustMode;          <span class="comment">\/\/\/&lt; Robust mode of array<\/span>$/;"	a
+l00066	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="psAstronomyErrors_8h.html#a35">00066<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_FIND_FAILED "Could not find metadata item, %s."<\/span>$/;"	a
+l00066	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="psDataManipErrors_8h.html#a35">00066<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_DIMEN_INVALID "Specified parameter, %s, has invalid dimensionality, %d."<\/span>$/;"	a
+l00066	docs/html/psImageErrors_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="psImageErrors_8h.html#a35">00066<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION "Must specify either PS_FFT_FORWARD or PS_FFT_REVERSE option."<\/span>$/;"	a
+l00066	docs/html/psImage_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="structpsImage.html#o16">00066<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga11">psC64<\/a>** <a class="code" href="structpsImage.html#o16">C64<\/a>;                   <span class="comment">\/\/\/&lt; Double-precision complex data.<\/span>$/;"	a
+l00066	docs/html/psMemory_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="structpsMemBlock.html#o0">00066<\/a>     <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsMemBlock.html#o0">startblock<\/a>;            <span class="comment">\/\/\/&lt; initialised to p_psMEMMAGIC<\/span>$/;"	a
+l00066	docs/html/psPhotometry_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="structpsPhotTransform.html#o5">00066<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a> sM;            <span class="comment">\/\/\/&lt; Secondary color reference<\/span>$/;"	a
+l00066	docs/html/psStats_8h-source.html	/^<a name="l00066"><\/a><a class="code" href="structpsStats.html#o8">00066<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustStdev;         <span class="comment">\/\/\/&lt; robust standard deviation of array<\/span>$/;"	a
+l00067	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="psAstronomyErrors_8h.html#a36">00067<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadata_FIND_INDEX_FAILED "Could not find metadata item at index %d."<\/span>$/;"	a
+l00067	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="psDataManipErrors_8h.html#a36">00067<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_VECTOR_EMPTY "Input psVector contains no elements.  No data to perform operation with."<\/span>$/;"	a
+l00067	docs/html/psImageErrors_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="psImageErrors_8h.html#a36">00067<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_FILENAME_NULL "Specified filename can not be NULL."<\/span>$/;"	a
+l00067	docs/html/psImage_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="structpsImage.html#o17">00067<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a>** <a class="code" href="structpsImage.html#o17">PTR<\/a>;                   <span class="comment">\/\/\/&lt; Void pointers.<\/span>$/;"	a
+l00067	docs/html/psMemory_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="structpsMemBlock.html#o1">00067<\/a> <span class="comment"><\/span>    <span class="keyword">struct <\/span><a class="code" href="structpsMemBlock.html">psMemBlock<\/a>* <a class="code" href="structpsMemBlock.html#o1">previousBlock<\/a>;  <span class="comment">\/\/\/&lt; previous block in allocation list<\/span>$/;"	a
+l00067	docs/html/psPhotometry_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="structpsPhotTransform.html#o6">00067<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> pA;                   <span class="comment">\/\/\/&lt; Color offset for references<\/span>$/;"	a
+l00067	docs/html/psStats_8h-source.html	/^<a name="l00067"><\/a><a class="code" href="structpsStats.html#o9">00067<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustUQ;            <span class="comment">\/\/\/&lt; robust upper quartile<\/span>$/;"	a
+l00068	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="psAstronomyErrors_8h.html#a37">00068<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID "Specified type, %d, is not supported."<\/span>$/;"	a
+l00068	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="psDataManipErrors_8h.html#a37">00068<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_IMAGE_EMPTY "Input psImage contains no pixels.  No data to perform operation with."<\/span>$/;"	a
+l00068	docs/html/psFunctions_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsPolynomial1D.html">00068<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00068	docs/html/psImageErrors_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="psImageErrors_8h.html#a37">00068<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_FILENAME_INVALID "Could not open file,'%s'.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00068	docs/html/psImage_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsImage.html#o18">00068<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a>*  <a class="code" href="structpsImage.html#o18">V<\/a>;                     <span class="comment">\/\/\/&lt; Pointer to data.<\/span>$/;"	a
+l00068	docs/html/psMemory_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsMemBlock.html#o2">00068<\/a> <span class="comment"><\/span>    <span class="keyword">struct <\/span><a class="code" href="structpsMemBlock.html">psMemBlock<\/a>* <a class="code" href="structpsMemBlock.html#o2">nextBlock<\/a>;      <span class="comment">\/\/\/&lt; next block allocation list<\/span>$/;"	a
+l00068	docs/html/psMetadata_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsMetadataItem.html">00068<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsMetadataItem.html">psMetadataItem<\/a>$/;"	a
+l00068	docs/html/psPhotometry_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsPhotTransform.html#o7">00068<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> sA;                   <span class="comment">\/\/\/&lt; Color offset for references<\/span>$/;"	a
+l00068	docs/html/psStats_8h-source.html	/^<a name="l00068"><\/a><a class="code" href="structpsStats.html#o10">00068<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> robustLQ;            <span class="comment">\/\/\/&lt; robust lower quartile<\/span>$/;"	a
+l00069	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="psAstronomyErrors_8h.html#a38">00069<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_EXTNUM_NOTPOSITIVE "Specified extension number, %d, is invalid.  Value must be positive if no extension name is given."<\/span>$/;"	a
+l00069	docs/html/psConstants_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="psConstants_8h.html#a11">00069<\/a> <span class="preprocessor">#define PS_INT_COMPARE(NAME1, NAME2, RVAL) \\<\/span>$/;"	a
+l00069	docs/html/psDataManipErrors_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="psDataManipErrors_8h.html#a38">00069<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMatrix_TRANSPOSE_MISMATCH "Number of rows do not match number of columns."<\/span>$/;"	a
+l00069	docs/html/psImageErrors_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="psImageErrors_8h.html#a38">00069<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_EXTNAME_INVALID "Could not find HDU with extension name '%s' in file %s.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00069	docs/html/psMemory_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="structpsMemBlock.html#o3">00069<\/a> <span class="comment"><\/span>    <a class="code" href="group__MemoryManagement.html#ga2">psFreeFcn<\/a> <a class="code" href="structpsMemBlock.html#o3">freeFcn<\/a>;                 <span class="comment">\/\/\/&lt; deallocator.  If NULL, use generic deallocation.<\/span>$/;"	a
+l00069	docs/html/psPhotometry_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="structpsPhotTransform.html#o8">00069<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPolynomial3D.html">psPolynomial3D<\/a> transform;   <span class="comment">\/\/\/&lt; Transformation from source to destination<\/span>$/;"	a
+l00069	docs/html/psStats_8h-source.html	/^<a name="l00069"><\/a><a class="code" href="structpsStats.html#o11">00069<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> robustN50;              <span class="comment">\/\/\/&lt;<\/span>$/;"	a
+l00070	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="psAstronomyErrors_8h.html#a39">00070<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_FITS_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."<\/span>$/;"	a
+l00070	docs/html/psFunctions_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsPolynomial1D.html#o0">00070<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00070	docs/html/psImageErrors_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="psImageErrors_8h.html#a39">00070<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_EXTNUM_INVALID "Could not find HDU #%d in file %s.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00070	docs/html/psImage_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsImage.html#o20">00070<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsImage.html">psImage<\/a>* <a class="code" href="structpsImage.html#o20">parent<\/a>;      <span class="comment">\/\/\/&lt; Parent, if a subimage.<\/span>$/;"	a
+l00070	docs/html/psList_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsListIterator.html">00070<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span>{$/;"	a
+l00070	docs/html/psMemory_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsMemBlock.html#o4">00070<\/a> <span class="comment"><\/span>    size_t <a class="code" href="structpsMemBlock.html#o4">userMemorySize<\/a>;             <span class="comment">\/\/\/&lt; the size of the user-portion of the memory block<\/span>$/;"	a
+l00070	docs/html/psMetadata_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsMetadataItem.html#o0">00070<\/a>     <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <span class="keywordtype">id<\/span>;                    <span class="comment">\/\/\/&lt; Unique ID for metadata item.<\/span>$/;"	a
+l00070	docs/html/psStats_8h-source.html	/^<a name="l00070"><\/a><a class="code" href="structpsStats.html#o12">00070<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> robustNfit;             <span class="comment">\/\/\/&lt;<\/span>$/;"	a
+l00071	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="psAstronomyErrors_8h.html#a40">00071<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_ADD_FAILED "Failed to add metadata item, %s."<\/span>$/;"	a
+l00071	docs/html/psCoord_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsPlaneTransform.html">00071<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00071	docs/html/psFunctions_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsPolynomial1D.html#o1">00071<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> n;                             <span class="comment">\/\/\/&lt; Number of terms<\/span>$/;"	a
+l00071	docs/html/psImageErrors_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="psImageErrors_8h.html#a40">00071<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN "Could not determine image data type for file %s.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00071	docs/html/psImage_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsImage.html#o21">00071<\/a> <span class="comment"><\/span>    <a class="code" href="structpsArray.html">psArray<\/a>* <a class="code" href="structpsImage.html#o21">children<\/a>;                 <span class="comment">\/\/\/&lt; Children of this region.<\/span>$/;"	a
+l00071	docs/html/psList_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsListIterator.html#o0">00071<\/a>     <a class="code" href="structpsList.html">psList<\/a>* list;                      <span class="comment">\/\/\/&lt; List iterator to works on<\/span>$/;"	a
+l00071	docs/html/psMemory_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsMemBlock.html#o5">00071<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__MemoryManagement.html#ga0">psMemoryId<\/a> <span class="keywordtype">id<\/span>;               <span class="comment">\/\/\/&lt; a unique ID for this allocation<\/span>$/;"	a
+l00071	docs/html/psMetadata_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsMetadataItem.html#o1">00071<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> *<a class="code" href="structpsMetadataItem.html#o1">name<\/a>;                        <span class="comment">\/\/\/&lt; Name of metadata item.<\/span>$/;"	a
+l00071	docs/html/psStats_8h-source.html	/^<a name="l00071"><\/a><a class="code" href="structpsStats.html#o13">00071<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> clippedMean;         <span class="comment">\/\/\/&lt; Nsigma clipped mean<\/span>$/;"	a
+l00072	docs/html/psAstrometry_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsFixedPattern.html">00072<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00072	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="psAstronomyErrors_8h.html#a41">00072<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED "Failed to open file '%s'. Check if it exists and it has the proper permissions."<\/span>$/;"	a
+l00072	docs/html/psFunctions_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsPolynomial1D.html#o2">00072<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> *coeff;                      <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00072	docs/html/psImageErrors_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="psImageErrors_8h.html#a41">00072<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN "Could not determine image dimensions for file %s.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00072	docs/html/psList_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsListIterator.html#o1">00072<\/a> <span class="comment"><\/span>    <a class="code" href="structpsListElem.html">psListElem<\/a>* cursor;                <span class="comment">\/\/\/&lt; current cursor position<\/span>$/;"	a
+l00072	docs/html/psMemory_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsMemBlock.html#o6">00072<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span> *<a class="code" href="structpsMemBlock.html#o6">file<\/a>;                  <span class="comment">\/\/\/&lt; set from __FILE__ in e.g. p_psAlloc<\/span>$/;"	a
+l00072	docs/html/psMetadata_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsMetadataItem.html#o2">00072<\/a> <span class="comment"><\/span>    <a class="code" href="group__Metadata.html#ga17">psMetadataType<\/a> <a class="code" href="structpsMetadataItem.html#o2">type<\/a>;               <span class="comment">\/\/\/&lt; Type of metadata item.<\/span>$/;"	a
+l00072	docs/html/psStats_8h-source.html	/^<a name="l00072"><\/a><a class="code" href="structpsStats.html#o14">00072<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> clippedStdev;        <span class="comment">\/\/\/&lt; standard deviation after clipping<\/span>$/;"	a
+l00073	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="psAstronomyErrors_8h.html#a42">00073<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR "More than one '%c' character not allowed.  Found on line %u of %s."<\/span>$/;"	a
+l00073	docs/html/psCoord_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsPlaneTransform.html#o0">00073<\/a>     <a class="code" href="structpsDPolynomial2D.html">psDPolynomial2D<\/a>* x;         <span class="comment">\/\/\/&lt; 2D polynomial transform of X coordinates<\/span>$/;"	a
+l00073	docs/html/psFunctions_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsPolynomial1D.html#o3">00073<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> *coeffErr;                   <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00073	docs/html/psImageErrors_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="psImageErrors_8h.html#a42">00073<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN "Could not determine image size for file %s.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00073	docs/html/psImage_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsImage.html#o22">00073<\/a>     <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsImage.html#o22">rawDataBuffer<\/a>;$/;"	a
+l00073	docs/html/psList_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsListIterator.html#o2">00073<\/a> <span class="comment"><\/span>    <span class="keywordtype">int<\/span> index;                         <span class="comment">\/\/\/&lt; the index number in the list<\/span>$/;"	a
+l00073	docs/html/psMemory_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsMemBlock.html#o7">00073<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structpsMemBlock.html#o7">lineno<\/a>;                  <span class="comment">\/\/\/&lt; set from __LINE__ in e.g. p_psAlloc<\/span>$/;"	a
+l00073	docs/html/psMetadata_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsMetadataItem.html#o3">00073<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga67">psElemType<\/a> <a class="code" href="structpsMetadataItem.html#o3">pType<\/a>;                  <span class="comment">\/\/\/&lt; Primitive data type<\/span>$/;"	a
+l00073	docs/html/psStats_8h-source.html	/^<a name="l00073"><\/a><a class="code" href="structpsStats.html#o15">00073<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> clippedNvalues;         <span class="comment">\/\/\/&lt; ???<\/span>$/;"	a
+l00074	docs/html/psAstrometry_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsFixedPattern.html#o0">00074<\/a>     <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of elements in x direction<\/span>$/;"	a
+l00074	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="psAstronomyErrors_8h.html#a43">00074<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL "Failed to read a metadata %s on line %u of %s."<\/span>$/;"	a
+l00074	docs/html/psCoord_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsPlaneTransform.html#o1">00074<\/a> <span class="comment"><\/span>    <a class="code" href="structpsDPolynomial2D.html">psDPolynomial2D<\/a>* y;         <span class="comment">\/\/\/&lt; 2D polynomial transform of Y coordinates<\/span>$/;"	a
+l00074	docs/html/psFunctions_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsPolynomial1D.html#o4">00074<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> *mask;                        <span class="comment">\/\/\/&lt; Coefficient mask<\/span>$/;"	a
+l00074	docs/html/psImageErrors_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="psImageErrors_8h.html#a43">00074<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#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."<\/span>$/;"	a
+l00074	docs/html/psList_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsListIterator.html#o3">00074<\/a> <span class="comment"><\/span>    <span class="keywordtype">bool<\/span> offEnd;                       <span class="comment">\/\/\/&lt; Iterator off the end?<\/span>$/;"	a
+l00074	docs/html/psMemory_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsMemBlock.html#o8">00074<\/a> <span class="comment"><\/span>    pthread_mutex_t <a class="code" href="structpsMemBlock.html#o8">refCounterMutex<\/a>;   <span class="comment">\/\/\/&lt; mutex to ensure exclusive access to reference counter<\/span>$/;"	a
+l00074	docs/html/psStats_8h-source.html	/^<a name="l00074"><\/a><a class="code" href="structpsStats.html#o16">00074<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> clipSigma;           <span class="comment">\/\/\/&lt; Nsigma used for clipping; user input<\/span>$/;"	a
+l00075	docs/html/psAstrometry_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="structpsFixedPattern.html#o1">00075<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of elements in y direction<\/span>$/;"	a
+l00075	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="psAstronomyErrors_8h.html#a44">00075<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID "Metadata type '%s', found on line %u of %s, is not invalid."<\/span>$/;"	a
+l00075	docs/html/psImageErrors_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="psImageErrors_8h.html#a44">00075<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, in file %s is not supported."<\/span>$/;"	a
+l00075	docs/html/psMemory_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="structpsMemBlock.html#o9">00075<\/a> <span class="comment"><\/span>    <a class="code" href="group__MemoryManagement.html#ga1">psReferenceCount<\/a> <a class="code" href="structpsMemBlock.html#o9">refCounter<\/a>;       <span class="comment">\/\/\/&lt; how many times pointer is referenced<\/span>$/;"	a
+l00075	docs/html/psMetadata_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="structpsMetadataItem.html#o4">00075<\/a>         <a class="code" href="group__DataContainer.html#ga13">psBool<\/a> <a class="code" href="structpsMetadataItem.html#o4">B<\/a>;                      <span class="comment">\/\/\/&lt; boolean data<\/span>$/;"	a
+l00075	docs/html/psStats_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="structpsStats.html#o17">00075<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> clipIter;               <span class="comment">\/\/\/&lt; Number of clipping iterations; user input<\/span>$/;"	a
+l00075	docs/html/psType_8h-source.html	/^<a name="l00075"><\/a><a class="code" href="group__DataContainer.html#ga15">00075<\/a> <span class="preprocessor">#define PS_TYPE_MASK PS_TYPE_U8        <\/span><span class="comment">\/**&lt; the psElemType to use for mask image *\/<\/span>$/;"	a
+l00076	docs/html/psAstrometry_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="structpsFixedPattern.html#o2">00076<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> x0;                         <span class="comment">\/\/\/&lt; X Position of 0,0 corner on focal plane<\/span>$/;"	a
+l00076	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="psAstronomyErrors_8h.html#a45">00076<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM "Duplicate Metadata item, %s, found on line %u of %s.  Overwrite not allowed."<\/span>$/;"	a
+l00076	docs/html/psImageErrors_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="psImageErrors_8h.html#a45">00076<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_READ_FAILED "Reading from FITS file %s failed.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00076	docs/html/psMemory_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="structpsMemBlock.html#o10">00076<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga13">psBool<\/a> <a class="code" href="structpsMemBlock.html#o10">persistent<\/a>;                   <span class="comment">\/\/\/&lt; marks if this non-user persistent data like error stack, etc.<\/span>$/;"	a
+l00076	docs/html/psMetadata_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="structpsMetadataItem.html#o5">00076<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> <a class="code" href="structpsMetadataItem.html#o5">S32<\/a>;                     <span class="comment">\/\/\/&lt; Signed 32-bit integer data.<\/span>$/;"	a
+l00076	docs/html/psStats_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="structpsStats.html#o18">00076<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> min;                 <span class="comment">\/\/\/&lt; minimum data value in array<\/span>$/;"	a
+l00076	docs/html/psType_8h-source.html	/^<a name="l00076"><\/a><a class="code" href="group__DataContainer.html#ga16">00076<\/a> <span class="preprocessor">#define PS_TYPE_MASK_DATA U8           <\/span><span class="comment">\/**&lt; the data member to use for mask image *\/<\/span>$/;"	a
+l00077	docs/html/psAstrometry_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="structpsFixedPattern.html#o3">00077<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> y0;                         <span class="comment">\/\/\/&lt; Y Position of 0,0 corner on focal plane<\/span>$/;"	a
+l00077	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="psAstronomyErrors_8h.html#a46">00077<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_PARSE_FAILED "Failed to parse the value '%s' of metadata item %s, type %s, on line %u of %s."<\/span>$/;"	a
+l00077	docs/html/psImageErrors_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="psImageErrors_8h.html#a46">00077<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED "Input psImage type, %s, is not supported."<\/span>$/;"	a
+l00077	docs/html/psMemory_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="structpsMemBlock.html#o11">00077<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsMemBlock.html#o11">endblock<\/a>;              <span class="comment">\/\/\/&lt; initialised to p_psMEMMAGIC<\/span>$/;"	a
+l00077	docs/html/psMetadata_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="structpsMetadataItem.html#o6">00077<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga8">psF32<\/a> <a class="code" href="structpsMetadataItem.html#o6">F32<\/a>;                     <span class="comment">\/\/\/&lt; Single-precision float data.<\/span>$/;"	a
+l00077	docs/html/psStats_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="structpsStats.html#o19">00077<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> max;                 <span class="comment">\/\/\/&lt; maximum data value in array<\/span>$/;"	a
+l00077	docs/html/psType_8h-source.html	/^<a name="l00077"><\/a><a class="code" href="group__DataContainer.html#ga17">00077<\/a> <span class="preprocessor">#define PS_TYPE_MASK_NAME "psU8"       <\/span><span class="comment">\/**&lt; the data type for mask as a string *\/<\/span>$/;"	a
+l00078	docs/html/psAstrometry_8h-source.html	/^<a name="l00078"><\/a><a class="code" href="structpsFixedPattern.html#o4">00078<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> xScale;                     <span class="comment">\/\/\/&lt; Scale of the grid in x direction<\/span>$/;"	a
+l00078	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00078"><\/a><a class="code" href="psAstronomyErrors_8h.html#a47">00078<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_NO_NAME "Failed to find key 'name' in table on line %u of %s."<\/span>$/;"	a
+l00078	docs/html/psImageErrors_8h-source.html	/^<a name="l00078"><\/a><a class="code" href="psImageErrors_8h.html#a47">00078<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID "Specified extension number, %d, must not exceed number of HDUs, %d, by more than one."<\/span>$/;"	a
+l00078	docs/html/psMetadata_8h-source.html	/^<a name="l00078"><\/a><a class="code" href="structpsMetadataItem.html#o7">00078<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga9">psF64<\/a> <a class="code" href="structpsMetadataItem.html#o7">F64<\/a>;                     <span class="comment">\/\/\/&lt; Double-precision float data.<\/span>$/;"	a
+l00078	docs/html/psStats_8h-source.html	/^<a name="l00078"><\/a><a class="code" href="structpsStats.html#o20">00078<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> binsize;             <span class="comment">\/\/\/&lt;<\/span>$/;"	a
+l00079	docs/html/psAstrometry_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="structpsFixedPattern.html#o5">00079<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> yScale;                     <span class="comment">\/\/\/&lt; Scale of the grid in x direction<\/span>$/;"	a
+l00079	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="psAstronomyErrors_8h.html#a48">00079<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_TYPE_INVALID_LINE_FILE "Specified type, %s, is not supported on line %u of %s."<\/span>$/;"	a
+l00079	docs/html/psConstants_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="psConstants_8h.html#a12">00079<\/a> <span class="preprocessor">#define PS_FLOAT_COMPARE(NAME1, NAME2, RVAL) \\<\/span>$/;"	a
+l00079	docs/html/psFunctions_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="structpsPolynomial2D.html">00079<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00079	docs/html/psImageErrors_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="psImageErrors_8h.html#a48">00079<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED "Could not create file,'%s'.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00079	docs/html/psMetadata_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="structpsMetadataItem.html#o8">00079<\/a> <span class="comment"><\/span>        <a class="code" href="structpsList.html">psList<\/a> *<a class="code" href="structpsMetadataItem.html#o8">list<\/a>;                  <span class="comment">\/\/\/&lt; List data.<\/span>$/;"	a
+l00079	docs/html/psMinimize_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="group__Stats.html#ga0">00079<\/a> <a class="code" href="structpsVector.html">psVector<\/a>* (*psMinimizeLMChi2Func)(<a class="code" href="structpsImage.html">psImage<\/a> *deriv,$/;"	a
+l00079	docs/html/psStats_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="structpsStats.html#o21">00079<\/a> <span class="comment"><\/span>    <a class="code" href="group__Stats.html#ga61">psStatsOptions<\/a> options;     <span class="comment">\/\/\/&lt; bitmask of calculated values<\/span>$/;"	a
+l00079	docs/html/psType_8h-source.html	/^<a name="l00079"><\/a><a class="code" href="group__DataContainer.html#ga14">00079<\/a> <span class="keyword">typedef<\/span> <a class="code" href="group__DataContainer.html#ga0">psU8<\/a> <a class="code" href="group__DataContainer.html#ga14">psMaskType<\/a>;               <span class="comment">\/\/\/&lt; the C datatype for a mask image<\/span>$/;"	a
+l00080	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00080"><\/a><a class="code" href="psAstronomyErrors_8h.html#a49">00080<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH "Start tag, %s and end tag, %s do not agree."<\/span>$/;"	a
+l00080	docs/html/psImageErrors_8h-source.html	/^<a name="l00080"><\/a><a class="code" href="psImageErrors_8h.html#a49">00080<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED "Could not create EXTNAME keyword for file,'%s'.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00080	docs/html/psMetadata_8h-source.html	/^<a name="l00080"><\/a><a class="code" href="structpsMetadataItem.html#o9">00080<\/a> <span class="comment"><\/span>        <a class="code" href="structpsMetadata.html">psMetadata<\/a> *<a class="code" href="structpsMetadataItem.html#o9">md<\/a>;                <span class="comment">\/\/\/&lt; Metadata data.<\/span>$/;"	a
+l00081	docs/html/psAstrometry_8h-source.html	/^<a name="l00081"><\/a><a class="code" href="structpsFixedPattern.html#o6">00081<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> p_ps_xRows;                    <span class="comment">\/\/\/&lt; Number of rows in the x member<\/span>$/;"	a
+l00081	docs/html/psAstronomyErrors_8h-source.html	/^<a name="l00081"><\/a><a class="code" href="psAstronomyErrors_8h.html#a50">00081<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN "Invalid end tag name, %s."<\/span>$/;"	a
+l00081	docs/html/psFunctions_8h-source.html	/^<a name="l00081"><\/a><a class="code" href="structpsPolynomial2D.html#o0">00081<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00081	docs/html/psImageErrors_8h-source.html	/^<a name="l00081"><\/a><a class="code" href="psImageErrors_8h.html#a50">00081<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED "Could not create HDU for writing psImage in file,'%s'.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00081	docs/html/psMetadata_8h-source.html	/^<a name="l00081"><\/a><a class="code" href="structpsMetadataItem.html#o10">00081<\/a> <span class="comment"><\/span>        <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> <a class="code" href="structpsMetadataItem.html#o10">V<\/a>;                       <span class="comment">\/\/\/&lt; Pointer to other type of data.<\/span>$/;"	a
+l00082	docs/html/psAstrometry_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="structpsFixedPattern.html#o7">00082<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> p_ps_xCols;                    <span class="comment">\/\/\/&lt; Number of cols in the x member<\/span>$/;"	a
+l00082	docs/html/psFunctions_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="structpsPolynomial2D.html#o1">00082<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00082	docs/html/psImageErrors_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="psImageErrors_8h.html#a51">00082<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageIO_WRITE_FAILED "Could not write psImage data to file,'%s'.\\nCFITSIO Error: %s"<\/span>$/;"	a
+l00082	docs/html/psImage_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="structpsRegion.html">00082<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00082	docs/html/psTime_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="group__Time.html#ga24">00082<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00082	docs/html/psType_8h-source.html	/^<a name="l00082"><\/a><a class="code" href="group__DataContainer.html#ga18">00082<\/a> <span class="preprocessor">#define PS_MIN_S8        INT8_MIN      <\/span><span class="comment">\/**&lt; minimum valid psS8 value *\/<\/span>$/;"	a
+l00083	docs/html/psAstrometry_8h-source.html	/^<a name="l00083"><\/a><a class="code" href="structpsFixedPattern.html#o8">00083<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> p_ps_yRows;                    <span class="comment">\/\/\/&lt; Number of rows in the y member<\/span>$/;"	a
+l00083	docs/html/psFunctions_8h-source.html	/^<a name="l00083"><\/a><a class="code" href="structpsPolynomial2D.html#o2">00083<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00083	docs/html/psImageErrors_8h-source.html	/^<a name="l00083"><\/a><a class="code" href="psImageErrors_8h.html#a52">00083<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_MAXMIN "Specified min value, %g, can not be greater than the specified max value, %g."<\/span>$/;"	a
+l00083	docs/html/psMetadata_8h-source.html	/^<a name="l00083"><\/a><a class="code" href="structpsMetadataItem.html#o12">00083<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> *<a class="code" href="structpsMetadataItem.html#o12">comment<\/a>;                     <span class="comment">\/\/\/&lt; Optional comment ("", not NULL).<\/span>$/;"	a
+l00083	docs/html/psType_8h-source.html	/^<a name="l00083"><\/a><a class="code" href="group__DataContainer.html#ga19">00083<\/a> <span class="preprocessor">#define PS_MIN_S16       INT16_MIN     <\/span><span class="comment">\/**&lt; minimum valid psS16 value *\/<\/span>$/;"	a
+l00084	docs/html/psAstrometry_8h-source.html	/^<a name="l00084"><\/a><a class="code" href="structpsFixedPattern.html#o9">00084<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> p_ps_yCols;                    <span class="comment">\/\/\/&lt; Number of cols in the y member<\/span>$/;"	a
+l00084	docs/html/psFunctions_8h-source.html	/^<a name="l00084"><\/a><a class="code" href="structpsPolynomial2D.html#o3">00084<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> **coeff;                     <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00084	docs/html/psImageErrors_8h-source.html	/^<a name="l00084"><\/a><a class="code" href="psImageErrors_8h.html#a53">00084<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#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."<\/span>$/;"	a
+l00084	docs/html/psImage_8h-source.html	/^<a name="l00084"><\/a><a class="code" href="structpsRegion.html#o0">00084<\/a>     <span class="keywordtype">double<\/span> x0;                         <span class="comment">\/\/\/&lt; the first column of the region.<\/span>$/;"	a
+l00084	docs/html/psType_8h-source.html	/^<a name="l00084"><\/a><a class="code" href="group__DataContainer.html#ga20">00084<\/a> <span class="preprocessor">#define PS_MIN_S32       INT32_MIN     <\/span><span class="comment">\/**&lt; minimum valid psS32 value *\/<\/span>$/;"	a
+l00085	docs/html/psAstrometry_8h-source.html	/^<a name="l00085"><\/a><a class="code" href="structpsFixedPattern.html#o10">00085<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> **x;                        <span class="comment">\/\/\/&lt; The grid of offsets in x<\/span>$/;"	a
+l00085	docs/html/psFunctions_8h-source.html	/^<a name="l00085"><\/a><a class="code" href="structpsPolynomial2D.html#o4">00085<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> **coeffErr;                  <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00085	docs/html/psImageErrors_8h-source.html	/^<a name="l00085"><\/a><a class="code" href="psImageErrors_8h.html#a54">00085<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#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."<\/span>$/;"	a
+l00085	docs/html/psImage_8h-source.html	/^<a name="l00085"><\/a><a class="code" href="structpsRegion.html#o1">00085<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> x1;                         <span class="comment">\/\/\/&lt; the last column of the region.<\/span>$/;"	a
+l00085	docs/html/psType_8h-source.html	/^<a name="l00085"><\/a><a class="code" href="group__DataContainer.html#ga21">00085<\/a> <span class="preprocessor">#define PS_MIN_S64       INT64_MIN     <\/span><span class="comment">\/**&lt; minimum valid psS64 value *\/<\/span>$/;"	a
+l00086	docs/html/psAstrometry_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="structpsFixedPattern.html#o11">00086<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> **y;                        <span class="comment">\/\/\/&lt; The grid of offsets in y<\/span>$/;"	a
+l00086	docs/html/psFunctions_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="structpsPolynomial2D.html#o5">00086<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> **mask;                       <span class="comment">\/\/\/&lt; Coefficients mask<\/span>$/;"	a
+l00086	docs/html/psImageErrors_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="psImageErrors_8h.html#a55">00086<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_OPERATION_NULL "Operation can not be NULL."<\/span>$/;"	a
+l00086	docs/html/psImage_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="structpsRegion.html#o2">00086<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> y0;                         <span class="comment">\/\/\/&lt; the first row of the region.<\/span>$/;"	a
+l00086	docs/html/psMemory_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="group__memCallback.html#ga0">00086<\/a> <span class="keyword">typedef<\/span> <a class="code" href="group__MemoryManagement.html#ga0">psMemoryId<\/a>(*<a class="code" href="group__memCallback.html#ga0">psMemAllocateCallback<\/a>) ($/;"	a
+l00086	docs/html/psType_8h-source.html	/^<a name="l00086"><\/a><a class="code" href="group__DataContainer.html#ga22">00086<\/a> <span class="preprocessor">#define PS_MIN_U8        0             <\/span><span class="comment">\/**&lt; minimum valid psU8 value *\/<\/span>$/;"	a
+l00087	docs/html/psConstants_8h-source.html	/^<a name="l00087"><\/a><a class="code" href="psConstants_8h.html#a13">00087<\/a> <span class="preprocessor">#define PS_FLOAT_CHECK_NON_EQUAL(NAME1, NAME2, RVAL) \\<\/span>$/;"	a
+l00087	docs/html/psImageErrors_8h-source.html	/^<a name="l00087"><\/a><a class="code" href="psImageErrors_8h.html#a56">00087<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH "Input overlay psImage type, %s, must match input psImage type, %s."<\/span>$/;"	a
+l00087	docs/html/psImage_8h-source.html	/^<a name="l00087"><\/a><a class="code" href="structpsRegion.html#o3">00087<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> y1;                         <span class="comment">\/\/\/&lt; the last row of the region.<\/span>$/;"	a
+l00087	docs/html/psType_8h-source.html	/^<a name="l00087"><\/a><a class="code" href="group__DataContainer.html#ga23">00087<\/a> <span class="preprocessor">#define PS_MIN_U16       0             <\/span><span class="comment">\/**&lt; minimum valid psU16 value *\/<\/span>$/;"	a
+l00088	docs/html/psImageErrors_8h-source.html	/^<a name="l00088"><\/a><a class="code" href="psImageErrors_8h.html#a57">00088<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#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].  "<\/span>$/;"	a
+l00088	docs/html/psType_8h-source.html	/^<a name="l00088"><\/a><a class="code" href="group__DataContainer.html#ga24">00088<\/a> <span class="preprocessor">#define PS_MIN_U32       0             <\/span><span class="comment">\/**&lt; minimum valid psU32 value *\/<\/span>$/;"	a
+l00088	docs/html/slalib_8h-source.html	/^<a name="l00088"><\/a><a class="code" href="slalib_8h.html#a0">00088<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define fslaAoppa sla_aoppa_<\/span>$/;"	a
+l00089	docs/html/psImageErrors_8h-source.html	/^<a name="l00089"><\/a><a class="code" href="psImageErrors_8h.html#a58">00089<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID "Specified operation, '%s', is not supported."<\/span>$/;"	a
+l00089	docs/html/psType_8h-source.html	/^<a name="l00089"><\/a><a class="code" href="group__DataContainer.html#ga25">00089<\/a> <span class="preprocessor">#define PS_MIN_U64       0             <\/span><span class="comment">\/**&lt; minimum valid psU64 value *\/<\/span>$/;"	a
+l00089	docs/html/slalib_8h-source.html	/^<a name="l00089"><\/a><a class="code" href="slalib_8h.html#a1">00089<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define fslaAopqk sla_aopqk_<\/span>$/;"	a
+l00090	docs/html/psCoord_8h-source.html	/^<a name="l00090"><\/a><a class="code" href="structpsPlaneDistort.html">00090<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00090	docs/html/psImageErrors_8h-source.html	/^<a name="l00090"><\/a><a class="code" href="psImageErrors_8h.html#a59">00090<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE "Specified scale value, %d, must be a positive value."<\/span>$/;"	a
+l00090	docs/html/psType_8h-source.html	/^<a name="l00090"><\/a><a class="code" href="group__DataContainer.html#ga26">00090<\/a> <span class="preprocessor">#define PS_MIN_F32       -FLT_MAX      <\/span><span class="comment">\/**&lt; minimum valid psF32 value *\/<\/span>$/;"	a
+l00090	docs/html/slalib_8h-source.html	/^<a name="l00090"><\/a><a class="code" href="slalib_8h.html#a2">00090<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define fslaOapqk sla_oapqk_<\/span>$/;"	a
+l00091	docs/html/psFunctions_8h-source.html	/^<a name="l00091"><\/a><a class="code" href="structpsPolynomial3D.html">00091<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00091	docs/html/psImageErrors_8h-source.html	/^<a name="l00091"><\/a><a class="code" href="psImageErrors_8h.html#a60">00091<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED "Specified interpolation mode, %d, is unsupported."<\/span>$/;"	a
+l00091	docs/html/psTrace_8h-source.html	/^<a name="l00091"><\/a><a class="code" href="psTrace_8h.html#a4">00091<\/a> <span class="preprocessor">#define psTrace(facil, level, ...) p_psTrace(facil, level, __VA_ARGS__)<\/span>$/;"	a
+l00091	docs/html/psType_8h-source.html	/^<a name="l00091"><\/a><a class="code" href="group__DataContainer.html#ga27">00091<\/a> <span class="preprocessor">#define PS_MIN_F64       -DBL_MAX      <\/span><span class="comment">\/**&lt; minimum valid psF64 value *\/<\/span>$/;"	a
+l00091	docs/html/slalib_8h-source.html	/^<a name="l00091"><\/a><a class="code" href="slalib_8h.html#a3">00091<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define fslaAirmas sla_airmas_<\/span>$/;"	a
+l00092	docs/html/psCoord_8h-source.html	/^<a name="l00092"><\/a><a class="code" href="structpsPlaneDistort.html#o0">00092<\/a>     <a class="code" href="structpsDPolynomial4D.html">psDPolynomial4D<\/a>* x;         <span class="comment">\/\/\/&lt; 4D polynomial transform of X coordinates<\/span>$/;"	a
+l00092	docs/html/psImageErrors_8h-source.html	/^<a name="l00092"><\/a><a class="code" href="psImageErrors_8h.html#a61">00092<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_SHIFT_NULL "Specified shift vectors can not be NULL."<\/span>$/;"	a
+l00092	docs/html/psType_8h-source.html	/^<a name="l00092"><\/a><a class="code" href="group__DataContainer.html#ga28">00092<\/a> <span class="preprocessor">#define PS_MIN_C32       -FLT_MAX      <\/span><span class="comment">\/**&lt; minimum valid real or imaginary psC32 value *\/<\/span>$/;"	a
+l00093	docs/html/psCoord_8h-source.html	/^<a name="l00093"><\/a><a class="code" href="structpsPlaneDistort.html#o1">00093<\/a> <span class="comment"><\/span>    <a class="code" href="structpsDPolynomial4D.html">psDPolynomial4D<\/a>* y;         <span class="comment">\/\/\/&lt; 4D polynomial transform of Y coordinates<\/span>$/;"	a
+l00093	docs/html/psFunctions_8h-source.html	/^<a name="l00093"><\/a><a class="code" href="structpsPolynomial3D.html#o0">00093<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00093	docs/html/psImageErrors_8h-source.html	/^<a name="l00093"><\/a><a class="code" href="psImageErrors_8h.html#a62">00093<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_KERNEL_NULL "Specified psKernel can not be NULL."<\/span>$/;"	a
+l00093	docs/html/psMinimize_8h-source.html	/^<a name="l00093"><\/a><a class="code" href="group__Stats.html#ga1">00093<\/a> float (*<a class="code" href="group__Stats.html#ga1">psMinimizePowellFunc<\/a>)(<span class="keyword">const<\/span> <a class="code" href="structpsVector.html">psVector<\/a> *params,$/;"	a
+l00093	docs/html/psType_8h-source.html	/^<a name="l00093"><\/a><a class="code" href="group__DataContainer.html#ga29">00093<\/a> <span class="preprocessor">#define PS_MIN_C64       -DBL_MAX      <\/span><span class="comment">\/**&lt; minimum valid real or imaginary psC32 value *\/<\/span>$/;"	a
+l00094	docs/html/psFunctions_8h-source.html	/^<a name="l00094"><\/a><a class="code" href="structpsPolynomial3D.html#o1">00094<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00094	docs/html/psImageErrors_8h-source.html	/^<a name="l00094"><\/a><a class="code" href="psImageErrors_8h.html#a63">00094<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH "Input t-, x-, and y-shift vector types (%s\/%s\/%s) must match."<\/span>$/;"	a
+l00094	docs/html/psTime_8h-source.html	/^<a name="l00094"><\/a><a class="code" href="structpsTime.html">00094<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsTime.html">psTime<\/a>$/;"	a
+l00095	docs/html/psFunctions_8h-source.html	/^<a name="l00095"><\/a><a class="code" href="structpsPolynomial3D.html#o2">00095<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00095	docs/html/psImageErrors_8h-source.html	/^<a name="l00095"><\/a><a class="code" href="psImageErrors_8h.html#a64">00095<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_FFT_FAILED "Failed to perform a fourier transform of input image."<\/span>$/;"	a
+l00095	docs/html/psMemory_8h-source.html	/^<a name="l00095"><\/a><a class="code" href="group__memCallback.html#ga1">00095<\/a> <span class="keyword">typedef<\/span> <a class="code" href="group__MemoryManagement.html#ga0">psMemoryId<\/a>(*<a class="code" href="group__memCallback.html#ga1">psMemFreeCallback<\/a>) ($/;"	a
+l00095	docs/html/psType_8h-source.html	/^<a name="l00095"><\/a><a class="code" href="group__DataContainer.html#ga30">00095<\/a> <span class="preprocessor">#define PS_MAX_S8        INT8_MAX      <\/span><span class="comment">\/**&lt; maximum valid psS8 value *\/<\/span>$/;"	a
+l00096	docs/html/psFunctions_8h-source.html	/^<a name="l00096"><\/a><a class="code" href="structpsPolynomial3D.html#o3">00096<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nZ;                            <span class="comment">\/\/\/&lt; Number of terms in z<\/span>$/;"	a
+l00096	docs/html/psImageErrors_8h-source.html	/^<a name="l00096"><\/a><a class="code" href="psImageErrors_8h.html#a65">00096<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED "Failed to perform a fourier transform of kernel."<\/span>$/;"	a
+l00096	docs/html/psTime_8h-source.html	/^<a name="l00096"><\/a><a class="code" href="structpsTime.html#o0">00096<\/a>     <a class="code" href="group__DataContainer.html#ga7">psS64<\/a> <a class="code" href="structpsTime.html#o0">sec<\/a>;          <span class="comment">\/\/\/&lt; Seconds since epoch, Jan 1, 1970.<\/span>$/;"	a
+l00096	docs/html/psType_8h-source.html	/^<a name="l00096"><\/a><a class="code" href="group__DataContainer.html#ga31">00096<\/a> <span class="preprocessor">#define PS_MAX_S16       INT16_MAX     <\/span><span class="comment">\/**&lt; maximum valid psS16 value *\/<\/span>$/;"	a
+l00097	docs/html/psFunctions_8h-source.html	/^<a name="l00097"><\/a><a class="code" href="structpsPolynomial3D.html#o4">00097<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> ***coeff;                    <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00097	docs/html/psImageErrors_8h-source.html	/^<a name="l00097"><\/a><a class="code" href="psImageErrors_8h.html#a66">00097<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE "Specified psKernel size, %dx%d, can not be larger than input psImage size, %dx%d. "<\/span>$/;"	a
+l00097	docs/html/psTime_8h-source.html	/^<a name="l00097"><\/a><a class="code" href="structpsTime.html#o1">00097<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> <a class="code" href="structpsTime.html#o1">usec<\/a>;         <span class="comment">\/\/\/&lt; Microseconds since last second.<\/span>$/;"	a
+l00097	docs/html/psType_8h-source.html	/^<a name="l00097"><\/a><a class="code" href="group__DataContainer.html#ga32">00097<\/a> <span class="preprocessor">#define PS_MAX_S32       INT32_MAX     <\/span><span class="comment">\/**&lt; maximum valid psS32 value *\/<\/span>$/;"	a
+l00098	docs/html/psFunctions_8h-source.html	/^<a name="l00098"><\/a><a class="code" href="structpsPolynomial3D.html#o5">00098<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> ***coeffErr;                 <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00098	docs/html/psImageErrors_8h-source.html	/^<a name="l00098"><\/a><a class="code" href="psImageErrors_8h.html#a67">00098<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_ERRORTEXT_psImage_COEFF_NULL "Polynomial coefficients cannot be NULL. "<\/span>$/;"	a
+l00098	docs/html/psTime_8h-source.html	/^<a name="l00098"><\/a><a class="code" href="structpsTime.html#o2">00098<\/a> <span class="comment"><\/span>    <a class="code" href="group__Time.html#ga24">psTimeType<\/a> <a class="code" href="structpsTime.html#o2">type<\/a>;    <span class="comment">\/\/\/&lt; Type of time.<\/span>$/;"	a
+l00098	docs/html/psType_8h-source.html	/^<a name="l00098"><\/a><a class="code" href="group__DataContainer.html#ga33">00098<\/a> <span class="preprocessor">#define PS_MAX_S64       INT64_MAX     <\/span><span class="comment">\/**&lt; maximum valid psS64 value *\/<\/span>$/;"	a
+l00099	docs/html/psAstrometry_8h-source.html	/^<a name="l00099"><\/a><a class="code" href="structpsReadout.html">00099<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00099	docs/html/psConstants_8h-source.html	/^<a name="l00099"><\/a><a class="code" href="psConstants_8h.html#a14">00099<\/a> <span class="preprocessor">#define PS_PTR_CHECK_NULL(NAME, RVAL) PS_PTR_CHECK_NULL_GENERAL(NAME, return RVAL)<\/span>$/;"	a
+l00099	docs/html/psFunctions_8h-source.html	/^<a name="l00099"><\/a><a class="code" href="structpsPolynomial3D.html#o6">00099<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> ***mask;                      <span class="comment">\/\/\/&lt; Coefficients mask<\/span>$/;"	a
+l00099	docs/html/psType_8h-source.html	/^<a name="l00099"><\/a><a class="code" href="group__DataContainer.html#ga34">00099<\/a> <span class="preprocessor">#define PS_MAX_U8        UINT8_MAX     <\/span><span class="comment">\/**&lt; maximum valid psU8 value *\/<\/span>$/;"	a
+l00100	docs/html/psConstants_8h-source.html	/^<a name="l00100"><\/a><a class="code" href="psConstants_8h.html#a15">00100<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_PTR_CHECK_NULL_GENERAL(NAME, CLEANUP) \\<\/span>$/;"	a
+l00100	docs/html/psType_8h-source.html	/^<a name="l00100"><\/a><a class="code" href="group__DataContainer.html#ga35">00100<\/a> <span class="preprocessor">#define PS_MAX_U16       UINT16_MAX    <\/span><span class="comment">\/**&lt; maximum valid psU16 value *\/<\/span>$/;"	a
+l00101	docs/html/psAstrometry_8h-source.html	/^<a name="l00101"><\/a><a class="code" href="structpsReadout.html#o0">00101<\/a>     <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> colBins;        <span class="comment">\/\/\/&lt; Amount of binning in x-dimension<\/span>$/;"	a
+l00101	docs/html/psType_8h-source.html	/^<a name="l00101"><\/a><a class="code" href="group__DataContainer.html#ga36">00101<\/a> <span class="preprocessor">#define PS_MAX_U32       UINT32_MAX    <\/span><span class="comment">\/**&lt; maximum valid psU32 value *\/<\/span>$/;"	a
+l00102	docs/html/psAstrometry_8h-source.html	/^<a name="l00102"><\/a><a class="code" href="structpsReadout.html#o1">00102<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga2">psU32<\/a> rowBins;        <span class="comment">\/\/\/&lt; Amount of binning in y-dimension<\/span>$/;"	a
+l00102	docs/html/psType_8h-source.html	/^<a name="l00102"><\/a><a class="code" href="group__DataContainer.html#ga37">00102<\/a> <span class="preprocessor">#define PS_MAX_U64       UINT64_MAX    <\/span><span class="comment">\/**&lt; maximum valid psU64 value *\/<\/span>$/;"	a
+l00103	docs/html/psAstrometry_8h-source.html	/^<a name="l00103"><\/a><a class="code" href="structpsReadout.html#o2">00103<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> col0;                    <span class="comment">\/\/\/&lt; Offset from the left of chip.<\/span>$/;"	a
+l00103	docs/html/psType_8h-source.html	/^<a name="l00103"><\/a><a class="code" href="group__DataContainer.html#ga38">00103<\/a> <span class="preprocessor">#define PS_MAX_F32       FLT_MAX       <\/span><span class="comment">\/**&lt; maximum valid psF32 value *\/<\/span>$/;"	a
+l00104	docs/html/psAstrometry_8h-source.html	/^<a name="l00104"><\/a><a class="code" href="structpsReadout.html#o3">00104<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> row0;                    <span class="comment">\/\/\/&lt; Offset from the bottom of chip.<\/span>$/;"	a
+l00104	docs/html/psFunctions_8h-source.html	/^<a name="l00104"><\/a><a class="code" href="structpsPolynomial4D.html">00104<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00104	docs/html/psType_8h-source.html	/^<a name="l00104"><\/a><a class="code" href="group__DataContainer.html#ga39">00104<\/a> <span class="preprocessor">#define PS_MAX_F64       DBL_MAX       <\/span><span class="comment">\/**&lt; maximum valid psF64 value *\/<\/span>$/;"	a
+l00105	docs/html/psType_8h-source.html	/^<a name="l00105"><\/a><a class="code" href="group__DataContainer.html#ga40">00105<\/a> <span class="preprocessor">#define PS_MAX_C32       FLT_MAX       <\/span><span class="comment">\/**&lt; maximum valid real or imaginary psC32 value *\/<\/span>$/;"	a
+l00106	docs/html/psAstrometry_8h-source.html	/^<a name="l00106"><\/a><a class="code" href="structpsReadout.html#o4">00106<\/a>     <a class="code" href="structpsImage.html">psImage<\/a>* image;                    <span class="comment">\/\/\/&lt; Imaging area of readout<\/span>$/;"	a
+l00106	docs/html/psFunctions_8h-source.html	/^<a name="l00106"><\/a><a class="code" href="structpsPolynomial4D.html#o0">00106<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00106	docs/html/psMemory_8h-source.html	/^<a name="l00106"><\/a><a class="code" href="group__memCallback.html#ga2">00106<\/a> <span class="keyword">typedef<\/span> void (*<a class="code" href="group__memCallback.html#ga2">psMemProblemCallback<\/a>) ($/;"	a
+l00106	docs/html/psType_8h-source.html	/^<a name="l00106"><\/a><a class="code" href="group__DataContainer.html#ga41">00106<\/a> <span class="preprocessor">#define PS_MAX_C64       DBL_MAX       <\/span><span class="comment">\/**&lt; maximum valid real or imaginary psC32 value *\/<\/span>$/;"	a
+l00107	docs/html/psAstrometry_8h-source.html	/^<a name="l00107"><\/a><a class="code" href="structpsReadout.html#o5">00107<\/a> <span class="comment"><\/span>    <a class="code" href="structpsImage.html">psImage<\/a>* mask;                     <span class="comment">\/\/\/&lt; Mask area for readout<\/span>$/;"	a
+l00107	docs/html/psCoord_8h-source.html	/^<a name="l00107"><\/a><a class="code" href="structpsSphereTransform.html">00107<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00107	docs/html/psFunctions_8h-source.html	/^<a name="l00107"><\/a><a class="code" href="structpsPolynomial4D.html#o1">00107<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nW;                            <span class="comment">\/\/\/&lt; Number of terms in w<\/span>$/;"	a
+l00108	docs/html/psAstrometry_8h-source.html	/^<a name="l00108"><\/a><a class="code" href="structpsReadout.html#o6">00108<\/a> <span class="comment"><\/span>    <a class="code" href="structpsList.html">psList<\/a>* objects;                   <span class="comment">\/\/\/&lt; Objects derived from Readout<\/span>$/;"	a
+l00108	docs/html/psConstants_8h-source.html	/^<a name="l00108"><\/a><a class="code" href="psConstants_8h.html#a16">00108<\/a> <span class="preprocessor">#define PS_PTR_CHECK_TYPE(NAME, TYPE, RVAL) \\<\/span>$/;"	a
+l00108	docs/html/psFunctions_8h-source.html	/^<a name="l00108"><\/a><a class="code" href="structpsPolynomial4D.html#o2">00108<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00108	docs/html/psType_8h-source.html	/^<a name="l00108"><\/a><a class="code" href="group__DataContainer.html#ga42">00108<\/a> <span class="preprocessor">#define PS_TYPE_BOOL_NAME "psBool"<\/span>$/;"	a
+l00109	docs/html/psAstrometry_8h-source.html	/^<a name="l00109"><\/a><a class="code" href="structpsReadout.html#o7">00109<\/a> <span class="comment"><\/span>    <a class="code" href="structpsMetadata.html">psMetadata<\/a>* metadata;              <span class="comment">\/\/\/&lt; Readout-level metadata<\/span>$/;"	a
+l00109	docs/html/psCoord_8h-source.html	/^<a name="l00109"><\/a><a class="code" href="structpsSphereTransform.html#o0">00109<\/a>     <span class="keywordtype">double<\/span> alphaP;                    <span class="comment">\/\/\/&lt; Longitude of the target system pole in the source system<\/span>$/;"	a
+l00109	docs/html/psFunctions_8h-source.html	/^<a name="l00109"><\/a><a class="code" href="structpsPolynomial4D.html#o3">00109<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00109	docs/html/psType_8h-source.html	/^<a name="l00109"><\/a><a class="code" href="group__DataContainer.html#ga43">00109<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_S8_NAME   "psS8"<\/span>$/;"	a
+l00110	docs/html/psCoord_8h-source.html	/^<a name="l00110"><\/a><a class="code" href="structpsSphereTransform.html#o1">00110<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> cosDeltaP;                 <span class="comment">\/\/\/&lt; Cosine of target pole latitude in the source system<\/span>$/;"	a
+l00110	docs/html/psFunctions_8h-source.html	/^<a name="l00110"><\/a><a class="code" href="structpsPolynomial4D.html#o4">00110<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nZ;                            <span class="comment">\/\/\/&lt; Number of terms in z<\/span>$/;"	a
+l00110	docs/html/psMinimize_8h-source.html	/^<a name="l00110"><\/a><a class="code" href="group__Stats.html#ga2">00110<\/a> <a class="code" href="structpsVector.html">psVector<\/a> *(*psMinimizeChi2PowellFunc)(<span class="keyword">const<\/span> <a class="code" href="structpsVector.html">psVector<\/a> *params,$/;"	a
+l00110	docs/html/psType_8h-source.html	/^<a name="l00110"><\/a><a class="code" href="group__DataContainer.html#ga44">00110<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_S16_NAME  "psS16"<\/span>$/;"	a
+l00111	docs/html/psCoord_8h-source.html	/^<a name="l00111"><\/a><a class="code" href="structpsSphereTransform.html#o2">00111<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> sinDeltaP;                 <span class="comment">\/\/\/&lt; Sine of target pole latitude in the source system<\/span>$/;"	a
+l00111	docs/html/psFunctions_8h-source.html	/^<a name="l00111"><\/a><a class="code" href="structpsPolynomial4D.html#o5">00111<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> ****coeff;                   <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00111	docs/html/psType_8h-source.html	/^<a name="l00111"><\/a><a class="code" href="group__DataContainer.html#ga45">00111<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_S32_NAME  "psS32"<\/span>$/;"	a
+l00112	docs/html/psCoord_8h-source.html	/^<a name="l00112"><\/a><a class="code" href="structpsSphereTransform.html#o3">00112<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> phiP;                      <span class="comment">\/\/\/&lt; Longitude of the ascending node in the target system<\/span>$/;"	a
+l00112	docs/html/psFunctions_8h-source.html	/^<a name="l00112"><\/a><a class="code" href="structpsPolynomial4D.html#o6">00112<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> ****coeffErr;                <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00112	docs/html/psType_8h-source.html	/^<a name="l00112"><\/a><a class="code" href="group__DataContainer.html#ga46">00112<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_S64_NAME  "psS64"<\/span>$/;"	a
+l00113	docs/html/psFunctions_8h-source.html	/^<a name="l00113"><\/a><a class="code" href="structpsPolynomial4D.html#o7">00113<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> ****mask;                     <span class="comment">\/\/\/&lt; Coefficients mask<\/span>$/;"	a
+l00113	docs/html/psType_8h-source.html	/^<a name="l00113"><\/a><a class="code" href="group__DataContainer.html#ga47">00113<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_U8_NAME   "psU8"<\/span>$/;"	a
+l00114	docs/html/psType_8h-source.html	/^<a name="l00114"><\/a><a class="code" href="group__DataContainer.html#ga48">00114<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_U16_NAME  "psU16"<\/span>$/;"	a
+l00115	docs/html/psType_8h-source.html	/^<a name="l00115"><\/a><a class="code" href="group__DataContainer.html#ga49">00115<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_U32_NAME  "psU32"<\/span>$/;"	a
+l00116	docs/html/psConstants_8h-source.html	/^<a name="l00116"><\/a><a class="code" href="psConstants_8h.html#a17">00116<\/a> <span class="preprocessor">#define PS_PTR_CHECK_DIMEN(NAME, DIMEN, RVAL) PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, return RVAL)<\/span>$/;"	a
+l00116	docs/html/psStats_8h-source.html	/^<a name="l00116"><\/a><a class="code" href="structpsHistogram.html">00116<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00116	docs/html/psType_8h-source.html	/^<a name="l00116"><\/a><a class="code" href="group__DataContainer.html#ga50">00116<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_U64_NAME  "psU64"<\/span>$/;"	a
+l00117	docs/html/psConstants_8h-source.html	/^<a name="l00117"><\/a><a class="code" href="psConstants_8h.html#a18">00117<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_PTR_CHECK_DIMEN_GENERAL(NAME, DIMEN, CLEANUP) \\<\/span>$/;"	a
+l00117	docs/html/psType_8h-source.html	/^<a name="l00117"><\/a><a class="code" href="group__DataContainer.html#ga51">00117<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_F32_NAME  "psF32"<\/span>$/;"	a
+l00118	docs/html/psStats_8h-source.html	/^<a name="l00118"><\/a><a class="code" href="structpsHistogram.html#o0">00118<\/a>     <a class="code" href="structpsVector.html">psVector<\/a>* bounds;                  <span class="comment">\/\/\/&lt; Bounds for the bins (type F32)<\/span>$/;"	a
+l00118	docs/html/psType_8h-source.html	/^<a name="l00118"><\/a><a class="code" href="group__DataContainer.html#ga52">00118<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_F64_NAME  "psF64"<\/span>$/;"	a
+l00119	docs/html/psStats_8h-source.html	/^<a name="l00119"><\/a><a class="code" href="structpsHistogram.html#o1">00119<\/a> <span class="comment"><\/span>    <a class="code" href="structpsVector.html">psVector<\/a>* nums;                    <span class="comment">\/\/\/&lt; Number in each of the bins (INT)<\/span>$/;"	a
+l00119	docs/html/psType_8h-source.html	/^<a name="l00119"><\/a><a class="code" href="group__DataContainer.html#ga53">00119<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_C32_NAME  "psC32"<\/span>$/;"	a
+l00120	docs/html/psError_8h-source.html	/^<a name="l00120"><\/a><a class="code" href="group__ErrorHandling.html#ga12">00120<\/a> <span class="preprocessor">#define psError(code,new,...) p_psError(__FILE__,__LINE__,__func__,code,new,__VA_ARGS__)<\/span>$/;"	a
+l00120	docs/html/psMemory_8h-source.html	/^<a name="l00120"><\/a><a class="code" href="group__memCallback.html#ga3">00120<\/a> <span class="keyword">typedef<\/span> <a class="code" href="group__DataContainer.html#ga12">psPtr<\/a> (*<a class="code" href="group__memCallback.html#ga3">psMemExhaustedCallback<\/a>) ($/;"	a
+l00120	docs/html/psStats_8h-source.html	/^<a name="l00120"><\/a><a class="code" href="structpsHistogram.html#o2">00120<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> minNum;                        <span class="comment">\/\/\/&lt; Number below the minimum<\/span>$/;"	a
+l00120	docs/html/psType_8h-source.html	/^<a name="l00120"><\/a><a class="code" href="group__DataContainer.html#ga54">00120<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_C64_NAME  "psC64"<\/span>$/;"	a
+l00121	docs/html/psCoord_8h-source.html	/^<a name="l00121"><\/a><a class="code" href="group__CoordinateTransform.html#ga16">00121<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00121	docs/html/psStats_8h-source.html	/^<a name="l00121"><\/a><a class="code" href="structpsHistogram.html#o3">00121<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> maxNum;                        <span class="comment">\/\/\/&lt; Number above the maximum<\/span>$/;"	a
+l00121	docs/html/psType_8h-source.html	/^<a name="l00121"><\/a><a class="code" href="group__DataContainer.html#ga55">00121<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_TYPE_PTR_NAME  "psPtr"<\/span>$/;"	a
+l00122	docs/html/psAstrometry_8h-source.html	/^<a name="l00122"><\/a><a class="code" href="structpsCell.html">00122<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00122	docs/html/psStats_8h-source.html	/^<a name="l00122"><\/a><a class="code" href="structpsHistogram.html#o4">00122<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga13">psBool<\/a> uniform;                      <span class="comment">\/\/\/&lt; Is it a uniform distribution?<\/span>$/;"	a
+l00123	docs/html/psType_8h-source.html	/^<a name="l00123"><\/a><a class="code" href="group__DataContainer.html#ga56">00123<\/a> <span class="preprocessor">#define PS_TYPE_NAME(value,type) \\<\/span>$/;"	a
+l00124	docs/html/psAstrometry_8h-source.html	/^<a name="l00124"><\/a><a class="code" href="structpsCell.html#o0">00124<\/a>     <a class="code" href="structpsArray.html">psArray<\/a>* readouts;                 <span class="comment">\/\/\/&lt; readouts from the cell<\/span>$/;"	a
+l00125	docs/html/psAstrometry_8h-source.html	/^<a name="l00125"><\/a><a class="code" href="structpsCell.html#o1">00125<\/a> <span class="comment"><\/span>    <a class="code" href="structpsMetadata.html">psMetadata<\/a>* metadata;              <span class="comment">\/\/\/&lt; cell-level metadata<\/span>$/;"	a
+l00126	docs/html/psConstants_8h-source.html	/^<a name="l00126"><\/a><a class="code" href="psConstants_8h.html#a19">00126<\/a> <span class="preprocessor">#define PS_PTR_CHECK_SIZE_EQUAL(PTR1, PTR2, RVAL) \\<\/span>$/;"	a
+l00127	docs/html/psAstrometry_8h-source.html	/^<a name="l00127"><\/a><a class="code" href="structpsCell.html#o2">00127<\/a>     <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* toChip;          <span class="comment">\/\/\/&lt; transformations from cell to chip coordinates<\/span>$/;"	a
+l00128	docs/html/psAstrometry_8h-source.html	/^<a name="l00128"><\/a><a class="code" href="structpsCell.html#o3">00128<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* fromChip;        <span class="comment">\/\/\/&lt; transformations from chip to cell coordinates<\/span>$/;"	a
+l00129	docs/html/psAstrometry_8h-source.html	/^<a name="l00129"><\/a><a class="code" href="structpsCell.html#o4">00129<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* toFPA;           <span class="comment">\/\/\/&lt; transformations from cell to FPA coordinates<\/span>$/;"	a
+l00130	docs/html/psAstrometry_8h-source.html	/^<a name="l00130"><\/a><a class="code" href="structpsCell.html#o5">00130<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* toTP;            <span class="comment">\/\/\/&lt; transformations from cell to tangent plane coordinates<\/span>$/;"	a
+l00131	docs/html/psAstrometry_8h-source.html	/^<a name="l00131"><\/a><a class="code" href="structpsCell.html#o6">00131<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* toSky;            <span class="comment">\/\/\/&lt; transformations from cell to tangent plane coordinates<\/span>$/;"	a
+l00133	docs/html/psAstrometry_8h-source.html	/^<a name="l00133"><\/a><a class="code" href="structpsCell.html#o7">00133<\/a>     <span class="keyword">struct <\/span><a class="code" href="structpsChip.html">psChip<\/a>* parent;             <span class="comment">\/\/\/&lt; chip in which contains this cell<\/span>$/;"	a
+l00134	docs/html/psConstants_8h-source.html	/^<a name="l00134"><\/a><a class="code" href="psConstants_8h.html#a20">00134<\/a> <span class="preprocessor">#define PS_PTR_CHECK_TYPE_EQUAL(PTR1, PTR2, RVAL) PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, return RVAL)<\/span>$/;"	a
+l00136	docs/html/psConstants_8h-source.html	/^<a name="l00136"><\/a><a class="code" href="psConstants_8h.html#a21">00136<\/a> <span class="preprocessor">#define PS_PTR_CHECK_TYPE_EQUAL_GENERAL(PTR1, PTR2, CLEANUP) \\<\/span>$/;"	a
+l00137	docs/html/psCoord_8h-source.html	/^<a name="l00137"><\/a><a class="code" href="structpsProjection.html">00137<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00139	docs/html/psCoord_8h-source.html	/^<a name="l00139"><\/a><a class="code" href="structpsProjection.html#o0">00139<\/a>     <span class="keywordtype">double<\/span> R;                   <span class="comment">\/\/\/&lt; Coordinates of projection center<\/span>$/;"	a
+l00140	docs/html/psCoord_8h-source.html	/^<a name="l00140"><\/a><a class="code" href="structpsProjection.html#o1">00140<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> D;                   <span class="comment">\/\/\/&lt; Coordinates of projection center<\/span>$/;"	a
+l00141	docs/html/psCoord_8h-source.html	/^<a name="l00141"><\/a><a class="code" href="structpsProjection.html#o2">00141<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> Xs;                  <span class="comment">\/\/\/&lt; plate-scale in X direction<\/span>$/;"	a
+l00142	docs/html/psCoord_8h-source.html	/^<a name="l00142"><\/a><a class="code" href="structpsProjection.html#o3">00142<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> Ys;                  <span class="comment">\/\/\/&lt; plate-scale in Y direction<\/span>$/;"	a
+l00143	docs/html/psCoord_8h-source.html	/^<a name="l00143"><\/a><a class="code" href="structpsProjection.html#o4">00143<\/a> <span class="comment"><\/span>    <a class="code" href="group__CoordinateTransform.html#ga16">psProjectionType<\/a> type;      <span class="comment">\/\/\/&lt; Projection type<\/span>$/;"	a
+l00145	docs/html/psAstrometry_8h-source.html	/^<a name="l00145"><\/a><a class="code" href="structpsChip.html">00145<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsChip.html">psChip<\/a>$/;"	a
+l00147	docs/html/psAstrometry_8h-source.html	/^<a name="l00147"><\/a><a class="code" href="structpsChip.html#o0">00147<\/a>     <a class="code" href="structpsArray.html">psArray<\/a>* <a class="code" href="structpsChip.html#o0">cells<\/a>;                    <span class="comment">\/\/\/&lt; cells in the chip<\/span>$/;"	a
+l00148	docs/html/psAstrometry_8h-source.html	/^<a name="l00148"><\/a><a class="code" href="structpsChip.html#o1">00148<\/a> <span class="comment"><\/span>    <a class="code" href="structpsMetadata.html">psMetadata<\/a>* <a class="code" href="structpsChip.html#o1">metadata<\/a>;              <span class="comment">\/\/\/&lt; chip-level metadata<\/span>$/;"	a
+l00148	docs/html/psConstants_8h-source.html	/^<a name="l00148"><\/a><a class="code" href="psConstants_8h.html#a22">00148<\/a> <span class="preprocessor">#define PS_VECTOR_CHECK_NULL(NAME, RVAL) PS_VECTOR_CHECK_NULL_GENERAL(NAME, return RVAL)<\/span>$/;"	a
+l00149	docs/html/psConstants_8h-source.html	/^<a name="l00149"><\/a><a class="code" href="psConstants_8h.html#a23">00149<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_CHECK_NULL_GENERAL(NAME, CLEANUP) \\<\/span>$/;"	a
+l00150	docs/html/psAstrometry_8h-source.html	/^<a name="l00150"><\/a><a class="code" href="structpsChip.html#o2">00150<\/a>     <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* <a class="code" href="structpsChip.html#o2">toFPA<\/a>;           <span class="comment">\/\/\/&lt; transformation from chip to FPA coordinates<\/span>$/;"	a
+l00151	docs/html/psAstrometry_8h-source.html	/^<a name="l00151"><\/a><a class="code" href="structpsChip.html#o3">00151<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneTransform.html">psPlaneTransform<\/a>* <a class="code" href="structpsChip.html#o3">fromFPA<\/a>;         <span class="comment">\/\/\/&lt; transformation from FPA to chip coordinates<\/span>$/;"	a
+l00152	docs/html/psCoord_8h-source.html	/^<a name="l00152"><\/a><a class="code" href="group__CoordinateTransform.html#ga17">00152<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00153	docs/html/psAstrometry_8h-source.html	/^<a name="l00153"><\/a><a class="code" href="structpsChip.html#o4">00153<\/a>     <span class="keyword">struct <\/span><a class="code" href="structpsFPA.html">psFPA<\/a>* <a class="code" href="structpsChip.html#o4">parent<\/a>;              <span class="comment">\/\/\/&lt; FPA which contains this chip<\/span>$/;"	a
+l00155	docs/html/slalib_8h-source.html	/^<a name="l00155"><\/a><a class="code" href="slalib_8h.html#a4">00155<\/a> <span class="preprocessor">#define slaAoppa(date,dut,elongm,phim,him,xp,yp,tdk,pmb,rh,wl,tlr,AOPRMS) \\<\/span>$/;"	a
+l00157	docs/html/psConstants_8h-source.html	/^<a name="l00157"><\/a><a class="code" href="psConstants_8h.html#a24">00157<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_CHECK_EMPTY(NAME, RVAL) \\<\/span>$/;"	a
+l00162	docs/html/psCoord_8h-source.html	/^<a name="l00162"><\/a><a class="code" href="group__CoordinateTransform.html#ga18">00162<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00165	docs/html/psConstants_8h-source.html	/^<a name="l00165"><\/a><a class="code" href="psConstants_8h.html#a25">00165<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_CHECK_TYPE_F32_OR_F64(NAME, RVAL) \\<\/span>$/;"	a
+l00170	docs/html/psAstrometry_8h-source.html	/^<a name="l00170"><\/a><a class="code" href="structpsFPA.html">00170<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsFPA.html">psFPA<\/a>$/;"	a
+l00172	docs/html/psAstrometry_8h-source.html	/^<a name="l00172"><\/a><a class="code" href="structpsFPA.html#o0">00172<\/a>     <a class="code" href="structpsArray.html">psArray<\/a>* <a class="code" href="structpsFPA.html#o0">chips<\/a>;                    <span class="comment">\/\/\/&lt; chips in the focal plane array<\/span>$/;"	a
+l00172	docs/html/psImage_8h-source.html	/^<a name="l00172"><\/a><a class="code" href="group__Image.html#ga23">00172<\/a> <span class="preprocessor">#define p_psImagePixelInterpolateFcns(TYPE) \\<\/span>$/;"	a
+l00172	docs/html/psType_8h-source.html	/^<a name="l00172"><\/a><a class="code" href="group__DataContainer.html#ga57">00172<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_BADPIXEL_BITMASK 0x0f<\/span>$/;"	a
+l00173	docs/html/psAstrometry_8h-source.html	/^<a name="l00173"><\/a><a class="code" href="structpsFPA.html#o1">00173<\/a> <span class="comment"><\/span>    <a class="code" href="structpsMetadata.html">psMetadata<\/a>* <a class="code" href="structpsFPA.html#o1">metadata<\/a>;              <span class="comment">\/\/\/&lt; focal-plane's metadata<\/span>$/;"	a
+l00173	docs/html/psConstants_8h-source.html	/^<a name="l00173"><\/a><a class="code" href="psConstants_8h.html#a26">00173<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_CHECK_TYPE(NAME, TYPE, RVAL) \\<\/span>$/;"	a
+l00173	docs/html/psType_8h-source.html	/^<a name="l00173"><\/a><a class="code" href="group__DataContainer.html#ga58">00173<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_GET_BADPIXEL(maskValue) (maskValue &amp; PS_BADPIXEL_BITMASK)<\/span>$/;"	a
+l00173	docs/html/slalib_8h-source.html	/^<a name="l00173"><\/a><a class="code" href="slalib_8h.html#a5">00173<\/a> <span class="preprocessor">#define slaAopqk(RAP,DAP,AOPRMS,AOB,ZOB,HOB,DOB,ROB) \\<\/span>$/;"	a
+l00175	docs/html/psAstrometry_8h-source.html	/^<a name="l00175"><\/a><a class="code" href="structpsFPA.html#o2">00175<\/a>     <a class="code" href="structpsPlaneDistort.html">psPlaneDistort<\/a>* <a class="code" href="structpsFPA.html#o2">fromTangentPlane<\/a>;  <span class="comment">\/\/\/&lt; transformation from tangent plane to focal plane<\/span>$/;"	a
+l00175	docs/html/psType_8h-source.html	/^<a name="l00175"><\/a><a class="code" href="group__DataContainer.html#ga59">00175<\/a> <span class="preprocessor">#define PS_IS_BADPIXEL(maskValue) (PS_GET_BADPIXEL(maskValue) != 0)<\/span>$/;"	a
+l00176	docs/html/psAstrometry_8h-source.html	/^<a name="l00176"><\/a><a class="code" href="structpsFPA.html#o3">00176<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPlaneDistort.html">psPlaneDistort<\/a>* <a class="code" href="structpsFPA.html#o3">toTangentPlane<\/a>;    <span class="comment">\/\/\/&lt; transformation from focal plane to tangent plane<\/span>$/;"	a
+l00177	docs/html/psAstrometry_8h-source.html	/^<a name="l00177"><\/a><a class="code" href="structpsFPA.html#o4">00177<\/a> <span class="comment"><\/span>    <a class="code" href="structpsFixedPattern.html">psFixedPattern<\/a>* <a class="code" href="structpsFPA.html#o4">pattern<\/a>;           <span class="comment">\/\/\/&lt; fixed pattern residual offsets<\/span>$/;"	a
+l00178	docs/html/psType_8h-source.html	/^<a name="l00178"><\/a><a class="code" href="group__DataContainer.html#ga60">00178<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_SET_BADPIXEL(maskValue, reasonCode) \\<\/span>$/;"	a
+l00179	docs/html/psAstrometry_8h-source.html	/^<a name="l00179"><\/a><a class="code" href="structpsFPA.html#o5">00179<\/a>     <span class="keyword">const<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsExposure.html">psExposure<\/a>* <a class="code" href="structpsFPA.html#o5">exposure<\/a>; <span class="comment">\/\/\/&lt; information about this exposure<\/span>$/;"	a
+l00180	docs/html/psAstrometry_8h-source.html	/^<a name="l00180"><\/a><a class="code" href="structpsFPA.html#o6">00180<\/a> <span class="comment"><\/span>    <a class="code" href="structpsGrommit.html">psGrommit<\/a> *<a class="code" href="structpsFPA.html#o6">grommit<\/a>;                <span class="comment">\/\/\/&lt; Wallace's grommit<\/span>$/;"	a
+l00181	docs/html/psConstants_8h-source.html	/^<a name="l00181"><\/a><a class="code" href="psConstants_8h.html#a27">00181<\/a> <span class="preprocessor">#define PS_VECTOR_CHECK_SIZE_EQUAL(VEC1, VEC2, RVAL) \\<\/span>$/;"	a
+l00182	docs/html/psAstrometry_8h-source.html	/^<a name="l00182"><\/a><a class="code" href="structpsFPA.html#o7">00182<\/a>     <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a>* <a class="code" href="structpsFPA.html#o7">colorPlus<\/a>;           <span class="comment">\/\/\/&lt; Color reference<\/span>$/;"	a
+l00183	docs/html/psAstrometry_8h-source.html	/^<a name="l00183"><\/a><a class="code" href="structpsFPA.html#o8">00183<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPhotSystem.html">psPhotSystem<\/a>* <a class="code" href="structpsFPA.html#o8">colorMinus<\/a>;          <span class="comment">\/\/\/&lt; Color reference<\/span>$/;"	a
+l00184	docs/html/psAstrometry_8h-source.html	/^<a name="l00184"><\/a><a class="code" href="structpsFPA.html#o9">00184<\/a> <span class="comment"><\/span>    <a class="code" href="structpsProjection.html">psProjection<\/a> *<a class="code" href="structpsFPA.html#o9">projection<\/a>;          <span class="comment">\/\/\/&lt; projection<\/span>$/;"	a
+l00184	docs/html/psType_8h-source.html	/^<a name="l00184"><\/a><a class="code" href="group__DataContainer.html#ga61">00184<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_IS_PSELEMTYPE_INT(x) ((x &amp; 0x100) == 0x100)<\/span>$/;"	a
+l00186	docs/html/psAstrometry_8h-source.html	/^<a name="l00186"><\/a><a class="code" href="structpsFPA.html#o10">00186<\/a>     <span class="keywordtype">float<\/span> <a class="code" href="structpsFPA.html#o10">rmsX<\/a>;                        <span class="comment">\/\/\/&lt; RMS for x transformation fits<\/span>$/;"	a
+l00186	docs/html/psType_8h-source.html	/^<a name="l00186"><\/a><a class="code" href="group__DataContainer.html#ga62">00186<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_IS_PSELEMTYPE_UNSIGNED(x) ((x &amp; 0x200) == 0x200)<\/span>$/;"	a
+l00187	docs/html/psAstrometry_8h-source.html	/^<a name="l00187"><\/a><a class="code" href="structpsFPA.html#o11">00187<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> <a class="code" href="structpsFPA.html#o11">rmsY<\/a>;                        <span class="comment">\/\/\/&lt; RMS for y transformation fits<\/span>$/;"	a
+l00188	docs/html/psAstrometry_8h-source.html	/^<a name="l00188"><\/a><a class="code" href="structpsFPA.html#o12">00188<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> <a class="code" href="structpsFPA.html#o12">chi2<\/a>;                        <span class="comment">\/\/\/&lt; chi^2 of astrometric solution<\/span>$/;"	a
+l00188	docs/html/psType_8h-source.html	/^<a name="l00188"><\/a><a class="code" href="group__DataContainer.html#ga63">00188<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_IS_PSELEMTYPE_REAL(x) ((x &amp; 0x400) == 0x400)<\/span>$/;"	a
+l00189	docs/html/psConstants_8h-source.html	/^<a name="l00189"><\/a><a class="code" href="psConstants_8h.html#a28">00189<\/a> <span class="preprocessor">#define PS_VECTOR_F64_TO_F32(X64, X32) \\<\/span>$/;"	a
+l00189	docs/html/slalib_8h-source.html	/^<a name="l00189"><\/a><a class="code" href="slalib_8h.html#a6">00189<\/a> <span class="preprocessor">#define slaOapqk(TYPE, OB1, OB2, AOPRMS, RAP, DAP) \\<\/span>$/;"	a
+l00190	docs/html/psImage_8h-source.html	/^<a name="l00190"><\/a><a class="code" href="group__Image.html#ga24">00190<\/a> <span class="preprocessor">#define p_psImagePixelInterpolateComplexFcns(TYPE) \\<\/span>$/;"	a
+l00190	docs/html/psType_8h-source.html	/^<a name="l00190"><\/a><a class="code" href="group__DataContainer.html#ga64">00190<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_IS_PSELEMTYPE_COMPLEX(x) ((x &amp; 0x800) == 0x800)<\/span>$/;"	a
+l00192	docs/html/psType_8h-source.html	/^<a name="l00192"><\/a><a class="code" href="group__DataContainer.html#ga65">00192<\/a> <span class="comment"><\/span><span class="preprocessor">#define PS_IS_PSELEMTYPE_BOOL(x) ((x &amp; 0x1000) == 0x1000)<\/span>$/;"	a
+l00194	docs/html/psType_8h-source.html	/^<a name="l00194"><\/a><a class="code" href="group__DataContainer.html#ga66">00194<\/a> <span class="comment"><\/span><span class="preprocessor">#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(psPtr) :(x &amp; 0xFF) )<\/span>$/;"	a
+l00195	docs/html/psConstants_8h-source.html	/^<a name="l00195"><\/a><a class="code" href="psConstants_8h.html#a29">00195<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_F32_TO_F64(X32, X64) \\<\/span>$/;"	a
+l00197	docs/html/psAstrometry_8h-source.html	/^<a name="l00197"><\/a><a class="code" href="structpsObservatory.html">00197<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00199	docs/html/psAstrometry_8h-source.html	/^<a name="l00199"><\/a><a class="code" href="structpsObservatory.html#o0">00199<\/a>     <span class="keyword">const<\/span> <span class="keywordtype">char<\/span>* name;                  <span class="comment">\/\/\/&lt; Name of observatory<\/span>$/;"	a
+l00199	docs/html/slalib_8h-source.html	/^<a name="l00199"><\/a><a class="code" href="slalib_8h.html#a7">00199<\/a> <span class="preprocessor">#define slaAirmas(ZD) fslaAirmas(&amp;ZD)<\/span>$/;"	a
+l00200	docs/html/psAstrometry_8h-source.html	/^<a name="l00200"><\/a><a class="code" href="structpsObservatory.html#o1">00200<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> latitude;             <span class="comment">\/\/\/&lt; Latitude of observatory, east positive (degrees?)<\/span>$/;"	a
+l00201	docs/html/psAstrometry_8h-source.html	/^<a name="l00201"><\/a><a class="code" href="structpsObservatory.html#o2">00201<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> longitude;            <span class="comment">\/\/\/&lt; Longitude of observatory (degrees?)<\/span>$/;"	a
+l00201	docs/html/psConstants_8h-source.html	/^<a name="l00201"><\/a><a class="code" href="psConstants_8h.html#a30">00201<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_PRINT(NAME) \\<\/span>$/;"	a
+l00201	docs/html/psType_8h-source.html	/^<a name="l00201"><\/a><a class="code" href="group__DataContainer.html#ga68">00201<\/a> <span class="keyword">typedef<\/span> <span class="keyword">enum<\/span> {$/;"	a
+l00202	docs/html/psAstrometry_8h-source.html	/^<a name="l00202"><\/a><a class="code" href="structpsObservatory.html#o3">00202<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> height;               <span class="comment">\/\/\/&lt; Height of observatory in meters<\/span>$/;"	a
+l00203	docs/html/psAstrometry_8h-source.html	/^<a name="l00203"><\/a><a class="code" href="structpsObservatory.html#o4">00203<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> tlr;                  <span class="comment">\/\/\/&lt; Tropospheric Lapse Rate<\/span>$/;"	a
+l00208	docs/html/psConstants_8h-source.html	/^<a name="l00208"><\/a><a class="code" href="psConstants_8h.html#a31">00208<\/a> <span class="preprocessor">#define PS_VECTOR_CONVERT_F64_TO_F32_STATIC(OLD, NEW_PTR32, NEW_STATIC32) \\<\/span>$/;"	a
+l00214	docs/html/psAstrometry_8h-source.html	/^<a name="l00214"><\/a><a class="code" href="structpsExposure.html">00214<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct <\/span><a class="code" href="structpsExposure.html">psExposure<\/a>$/;"	a
+l00215	docs/html/psType_8h-source.html	/^<a name="l00215"><\/a><a class="code" href="structpsType.html">00215<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00216	docs/html/psAstrometry_8h-source.html	/^<a name="l00216"><\/a><a class="code" href="structpsExposure.html#o0">00216<\/a>     <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o0">ra<\/a>;                   <span class="comment">\/\/\/&lt; Telescope boresight, right ascention<\/span>$/;"	a
+l00217	docs/html/psAstrometry_8h-source.html	/^<a name="l00217"><\/a><a class="code" href="structpsExposure.html#o1">00217<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o1">dec<\/a>;                  <span class="comment">\/\/\/&lt; Telescope boresight, declination<\/span>$/;"	a
+l00217	docs/html/psType_8h-source.html	/^<a name="l00217"><\/a><a class="code" href="structpsType.html#o0">00217<\/a>     <a class="code" href="group__DataContainer.html#ga67">psElemType<\/a> type;            <span class="comment">\/\/\/&lt; Primitive type.<\/span>$/;"	a
+l00218	docs/html/psAstrometry_8h-source.html	/^<a name="l00218"><\/a><a class="code" href="structpsExposure.html#o2">00218<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o2">hourAngle<\/a>;            <span class="comment">\/\/\/&lt; Hour angle<\/span>$/;"	a
+l00218	docs/html/psType_8h-source.html	/^<a name="l00218"><\/a><a class="code" href="structpsType.html#o1">00218<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga68">psDimen<\/a> dimen;              <span class="comment">\/\/\/&lt; Dimensionality.<\/span>$/;"	a
+l00219	docs/html/psAstrometry_8h-source.html	/^<a name="l00219"><\/a><a class="code" href="structpsExposure.html#o3">00219<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o3">zenithDistance<\/a>;       <span class="comment">\/\/\/&lt; Zenith distance<\/span>$/;"	a
+l00220	docs/html/psAstrometry_8h-source.html	/^<a name="l00220"><\/a><a class="code" href="structpsExposure.html#o4">00220<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o4">azimuth<\/a>;              <span class="comment">\/\/\/&lt; Azimuth<\/span>$/;"	a
+l00221	docs/html/psAstrometry_8h-source.html	/^<a name="l00221"><\/a><a class="code" href="structpsExposure.html#o5">00221<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="structpsTime.html">psTime<\/a>* <a class="code" href="structpsExposure.html#o5">time<\/a>;                <span class="comment">\/\/\/&lt; Time of observation<\/span>$/;"	a
+l00221	docs/html/psConstants_8h-source.html	/^<a name="l00221"><\/a><a class="code" href="psConstants_8h.html#a32">00221<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_CONVERT_F32_TO_F64_STATIC(OLD, NEW_PTR64, NEW_STATIC64) \\<\/span>$/;"	a
+l00222	docs/html/psAstrometry_8h-source.html	/^<a name="l00222"><\/a><a class="code" href="structpsExposure.html#o6">00222<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o6">rotAngle<\/a>;              <span class="comment">\/\/\/&lt; Rotator position angle in degrees? XXX: see bug#209<\/span>$/;"	a
+l00223	docs/html/psAstrometry_8h-source.html	/^<a name="l00223"><\/a><a class="code" href="structpsExposure.html#o7">00223<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o7">temperature<\/a>;           <span class="comment">\/\/\/&lt; Air temperature in Kelvin<\/span>$/;"	a
+l00224	docs/html/psAstrometry_8h-source.html	/^<a name="l00224"><\/a><a class="code" href="structpsExposure.html#o8">00224<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o8">pressure<\/a>;              <span class="comment">\/\/\/&lt; Air pressure in mB<\/span>$/;"	a
+l00225	docs/html/psAstrometry_8h-source.html	/^<a name="l00225"><\/a><a class="code" href="structpsExposure.html#o9">00225<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o9">humidity<\/a>;              <span class="comment">\/\/\/&lt; Relative humidity, for refraction<\/span>$/;"	a
+l00226	docs/html/psAstrometry_8h-source.html	/^<a name="l00226"><\/a><a class="code" href="structpsExposure.html#o10">00226<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o10">exposureTime<\/a>;          <span class="comment">\/\/\/&lt; Exposure time<\/span>$/;"	a
+l00227	docs/html/psAstrometry_8h-source.html	/^<a name="l00227"><\/a><a class="code" href="structpsExposure.html#o11">00227<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o11">wavelength<\/a>;            <span class="comment">\/\/\/&lt; Wavelength in microns<\/span>$/;"	a
+l00228	docs/html/psAstrometry_8h-source.html	/^<a name="l00228"><\/a><a class="code" href="structpsExposure.html#o12">00228<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <a class="code" href="structpsObservatory.html">psObservatory<\/a>* <a class="code" href="structpsExposure.html#o12">observatory<\/a>;  <span class="comment">\/\/\/&lt; Observatory data<\/span>$/;"	a
+l00231	docs/html/psAstrometry_8h-source.html	/^<a name="l00231"><\/a><a class="code" href="structpsExposure.html#o13">00231<\/a>     <span class="keyword">const<\/span> <span class="keywordtype">double<\/span> <a class="code" href="structpsExposure.html#o13">lst<\/a>;                  <span class="comment">\/\/\/&lt; Local Sidereal Time<\/span>$/;"	a
+l00232	docs/html/psAstrometry_8h-source.html	/^<a name="l00232"><\/a><a class="code" href="structpsExposure.html#o14">00232<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o14">positionAngle<\/a>;         <span class="comment">\/\/\/&lt; Position angle<\/span>$/;"	a
+l00233	docs/html/psAstrometry_8h-source.html	/^<a name="l00233"><\/a><a class="code" href="structpsExposure.html#o15">00233<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o15">parallacticAngle<\/a>;      <span class="comment">\/\/\/&lt; Parallactic angle<\/span>$/;"	a
+l00233	docs/html/psFunctions_8h-source.html	/^<a name="l00233"><\/a><a class="code" href="structpsDPolynomial1D.html">00233<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00234	docs/html/psAstrometry_8h-source.html	/^<a name="l00234"><\/a><a class="code" href="structpsExposure.html#o16">00234<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o16">airmass<\/a>;               <span class="comment">\/\/\/&lt; Airmass, calculated from zenith distance<\/span>$/;"	a
+l00234	docs/html/psConstants_8h-source.html	/^<a name="l00234"><\/a><a class="code" href="psConstants_8h.html#a33">00234<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_GEN_YERR_STATIC_F32(VEC, N) \\<\/span>$/;"	a
+l00235	docs/html/psAstrometry_8h-source.html	/^<a name="l00235"><\/a><a class="code" href="structpsExposure.html#o17">00235<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">float<\/span> <a class="code" href="structpsExposure.html#o17">parallacticFactor<\/a>;     <span class="comment">\/\/\/&lt; Parallactic factor<\/span>$/;"	a
+l00235	docs/html/psFunctions_8h-source.html	/^<a name="l00235"><\/a><a class="code" href="structpsDPolynomial1D.html#o0">00235<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00236	docs/html/psAstrometry_8h-source.html	/^<a name="l00236"><\/a><a class="code" href="structpsExposure.html#o18">00236<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span>* <a class="code" href="structpsExposure.html#o18">cameraName<\/a>;            <span class="comment">\/\/\/&lt; name of camera which provided exposure<\/span>$/;"	a
+l00236	docs/html/psFunctions_8h-source.html	/^<a name="l00236"><\/a><a class="code" href="structpsDPolynomial1D.html#o1">00236<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> n;                             <span class="comment">\/\/\/&lt; Number of terms<\/span>$/;"	a
+l00237	docs/html/psAstrometry_8h-source.html	/^<a name="l00237"><\/a><a class="code" href="structpsExposure.html#o19">00237<\/a> <span class="comment"><\/span>    <span class="keyword">const<\/span> <span class="keywordtype">char<\/span>* <a class="code" href="structpsExposure.html#o19">telescopeName<\/a>;         <span class="comment">\/\/\/&lt; name of telescope which provided exposure<\/span>$/;"	a
+l00237	docs/html/psFunctions_8h-source.html	/^<a name="l00237"><\/a><a class="code" href="structpsDPolynomial1D.html#o2">00237<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> *coeff;                     <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00238	docs/html/psFunctions_8h-source.html	/^<a name="l00238"><\/a><a class="code" href="structpsDPolynomial1D.html#o3">00238<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> *coeffErr;                  <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00239	docs/html/psFunctions_8h-source.html	/^<a name="l00239"><\/a><a class="code" href="structpsDPolynomial1D.html#o4">00239<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> *mask;                        <span class="comment">\/\/\/&lt; Coefficient mask<\/span>$/;"	a
+l00242	docs/html/psConstants_8h-source.html	/^<a name="l00242"><\/a><a class="code" href="psConstants_8h.html#a34">00242<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_GEN_YERR_STATIC_F64(VEC, N) \\<\/span>$/;"	a
+l00244	docs/html/psFunctions_8h-source.html	/^<a name="l00244"><\/a><a class="code" href="structpsDPolynomial2D.html">00244<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00246	docs/html/psFunctions_8h-source.html	/^<a name="l00246"><\/a><a class="code" href="structpsDPolynomial2D.html#o0">00246<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00247	docs/html/psFunctions_8h-source.html	/^<a name="l00247"><\/a><a class="code" href="structpsDPolynomial2D.html#o1">00247<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00248	docs/html/psFunctions_8h-source.html	/^<a name="l00248"><\/a><a class="code" href="structpsDPolynomial2D.html#o2">00248<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00249	docs/html/psFunctions_8h-source.html	/^<a name="l00249"><\/a><a class="code" href="structpsDPolynomial2D.html#o3">00249<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> **coeff;                    <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00250	docs/html/psConstants_8h-source.html	/^<a name="l00250"><\/a><a class="code" href="psConstants_8h.html#a35">00250<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_GEN_X_INDEX_STATIC_F32(VEC, N) \\<\/span>$/;"	a
+l00250	docs/html/psFunctions_8h-source.html	/^<a name="l00250"><\/a><a class="code" href="structpsDPolynomial2D.html#o4">00250<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> **coeffErr;                 <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00251	docs/html/psFunctions_8h-source.html	/^<a name="l00251"><\/a><a class="code" href="structpsDPolynomial2D.html#o5">00251<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> **mask;                       <span class="comment">\/\/\/&lt; Coefficients mask<\/span>$/;"	a
+l00256	docs/html/psFunctions_8h-source.html	/^<a name="l00256"><\/a><a class="code" href="structpsDPolynomial3D.html">00256<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00258	docs/html/psConstants_8h-source.html	/^<a name="l00258"><\/a><a class="code" href="psConstants_8h.html#a36">00258<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_GEN_X_INDEX_STATIC_F64(VEC, N) \\<\/span>$/;"	a
+l00258	docs/html/psFunctions_8h-source.html	/^<a name="l00258"><\/a><a class="code" href="structpsDPolynomial3D.html#o0">00258<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00259	docs/html/psFunctions_8h-source.html	/^<a name="l00259"><\/a><a class="code" href="structpsDPolynomial3D.html#o1">00259<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00260	docs/html/psFunctions_8h-source.html	/^<a name="l00260"><\/a><a class="code" href="structpsDPolynomial3D.html#o2">00260<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00261	docs/html/psFunctions_8h-source.html	/^<a name="l00261"><\/a><a class="code" href="structpsDPolynomial3D.html#o3">00261<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nZ;                            <span class="comment">\/\/\/&lt; Number of terms in z<\/span>$/;"	a
+l00262	docs/html/psFunctions_8h-source.html	/^<a name="l00262"><\/a><a class="code" href="structpsDPolynomial3D.html#o4">00262<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> ***coeff;                   <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00263	docs/html/psFunctions_8h-source.html	/^<a name="l00263"><\/a><a class="code" href="structpsDPolynomial3D.html#o5">00263<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> ***coeffErr;                <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00264	docs/html/psFunctions_8h-source.html	/^<a name="l00264"><\/a><a class="code" href="structpsDPolynomial3D.html#o6">00264<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> ***mask;                      <span class="comment">\/\/\/&lt; Coefficient mask<\/span>$/;"	a
+l00266	docs/html/psConstants_8h-source.html	/^<a name="l00266"><\/a><a class="code" href="psConstants_8h.html#a37">00266<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_GEN_STATIC_RECYCLED(NAME, SIZE, TYPE) \\<\/span>$/;"	a
+l00269	docs/html/psFunctions_8h-source.html	/^<a name="l00269"><\/a><a class="code" href="structpsDPolynomial4D.html">00269<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00271	docs/html/psFunctions_8h-source.html	/^<a name="l00271"><\/a><a class="code" href="structpsDPolynomial4D.html#o0">00271<\/a>     <a class="code" href="group__Stats.html#ga60">psPolynomialType<\/a> type;             <span class="comment">\/\/\/&lt; Polynomial type<\/span>$/;"	a
+l00272	docs/html/psConstants_8h-source.html	/^<a name="l00272"><\/a><a class="code" href="psConstants_8h.html#a38">00272<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_VECTOR_DECLARE_ALLOC_STATIC(NAME, SIZE, TYPE) \\<\/span>$/;"	a
+l00272	docs/html/psFunctions_8h-source.html	/^<a name="l00272"><\/a><a class="code" href="structpsDPolynomial4D.html#o1">00272<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nW;                            <span class="comment">\/\/\/&lt; Number of terms in w<\/span>$/;"	a
+l00273	docs/html/psFunctions_8h-source.html	/^<a name="l00273"><\/a><a class="code" href="structpsDPolynomial4D.html#o2">00273<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nX;                            <span class="comment">\/\/\/&lt; Number of terms in x<\/span>$/;"	a
+l00274	docs/html/psFunctions_8h-source.html	/^<a name="l00274"><\/a><a class="code" href="structpsDPolynomial4D.html#o3">00274<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nY;                            <span class="comment">\/\/\/&lt; Number of terms in y<\/span>$/;"	a
+l00275	docs/html/psFunctions_8h-source.html	/^<a name="l00275"><\/a><a class="code" href="structpsDPolynomial4D.html#o4">00275<\/a> <span class="comment"><\/span>    <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> nZ;                            <span class="comment">\/\/\/&lt; Number of terms in z<\/span>$/;"	a
+l00276	docs/html/psFunctions_8h-source.html	/^<a name="l00276"><\/a><a class="code" href="structpsDPolynomial4D.html#o5">00276<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> ****coeff;                  <span class="comment">\/\/\/&lt; Coefficients<\/span>$/;"	a
+l00277	docs/html/psFunctions_8h-source.html	/^<a name="l00277"><\/a><a class="code" href="structpsDPolynomial4D.html#o6">00277<\/a> <span class="comment"><\/span>    <span class="keywordtype">double<\/span> ****coeffErr;               <span class="comment">\/\/\/&lt; Error in coefficients<\/span>$/;"	a
+l00278	docs/html/psFunctions_8h-source.html	/^<a name="l00278"><\/a><a class="code" href="structpsDPolynomial4D.html#o7">00278<\/a> <span class="comment"><\/span>    <span class="keywordtype">char<\/span> ****mask;                     <span class="comment">\/\/\/&lt; Coefficients mask<\/span>$/;"	a
+l00283	docs/html/psConstants_8h-source.html	/^<a name="l00283"><\/a><a class="code" href="psConstants_8h.html#a39">00283<\/a> <span class="preprocessor">#define PS_POLY_CHECK_NULL(NAME, RVAL) \\<\/span>$/;"	a
+l00291	docs/html/psConstants_8h-source.html	/^<a name="l00291"><\/a><a class="code" href="psConstants_8h.html#a40">00291<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_CHECK_TYPE(NAME, TYPE, RVAL) \\<\/span>$/;"	a
+l00301	docs/html/psConstants_8h-source.html	/^<a name="l00301"><\/a><a class="code" href="psConstants_8h.html#a41">00301<\/a> <span class="preprocessor">#define PS_POLY_1D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00308	docs/html/psConstants_8h-source.html	/^<a name="l00308"><\/a><a class="code" href="psConstants_8h.html#a42">00308<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_2D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00315	docs/html/psConstants_8h-source.html	/^<a name="l00315"><\/a><a class="code" href="psConstants_8h.html#a43">00315<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_3D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00322	docs/html/psConstants_8h-source.html	/^<a name="l00322"><\/a><a class="code" href="psConstants_8h.html#a44">00322<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_4D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00329	docs/html/psConstants_8h-source.html	/^<a name="l00329"><\/a><a class="code" href="psConstants_8h.html#a45">00329<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_1D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00336	docs/html/psConstants_8h-source.html	/^<a name="l00336"><\/a><a class="code" href="psConstants_8h.html#a46">00336<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_2D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00343	docs/html/psConstants_8h-source.html	/^<a name="l00343"><\/a><a class="code" href="psConstants_8h.html#a47">00343<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_3D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00350	docs/html/psConstants_8h-source.html	/^<a name="l00350"><\/a><a class="code" href="psConstants_8h.html#a48">00350<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_POLY_4D_D_DECLARE_ALLOC_STATIC(NAME, ORDER, TYPE) \\<\/span>$/;"	a
+l00360	docs/html/psConstants_8h-source.html	/^<a name="l00360"><\/a><a class="code" href="psConstants_8h.html#a49">00360<\/a> <span class="preprocessor">#define PS_IMAGE_CHECK_NULL(NAME, RVAL) PS_IMAGE_CHECK_NULL_GENERAL(NAME, return RVAL)<\/span>$/;"	a
+l00361	docs/html/psConstants_8h-source.html	/^<a name="l00361"><\/a><a class="code" href="psConstants_8h.html#a50">00361<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_IMAGE_CHECK_NULL_GENERAL(NAME, CLEANUP) \\<\/span>$/;"	a
+l00369	docs/html/psConstants_8h-source.html	/^<a name="l00369"><\/a><a class="code" href="psConstants_8h.html#a51">00369<\/a> <span class="preprocessor">#define PS_IMAGE_CHECK_EMPTY(NAME, RVAL) PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, return RVAL)<\/span>$/;"	a
+l00370	docs/html/psConstants_8h-source.html	/^<a name="l00370"><\/a><a class="code" href="psConstants_8h.html#a52">00370<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_IMAGE_CHECK_EMPTY_GENERAL(NAME, CLEANUP) \\<\/span>$/;"	a
+l00378	docs/html/psConstants_8h-source.html	/^<a name="l00378"><\/a><a class="code" href="psConstants_8h.html#a53">00378<\/a> <span class="preprocessor">#define PS_IMAGE_CHECK_TYPE(NAME, TYPE, RVAL) \\<\/span>$/;"	a
+l00386	docs/html/psConstants_8h-source.html	/^<a name="l00386"><\/a><a class="code" href="psConstants_8h.html#a54">00386<\/a> <span class="preprocessor">#define PS_IMAGE_CHECK_SIZE_EQUAL(NAME1, NAME2, RVAL) \\<\/span>$/;"	a
+l00394	docs/html/psFunctions_8h-source.html	/^<a name="l00394"><\/a><a class="code" href="structpsSpline1D.html">00394<\/a> <span class="keyword">typedef<\/span> <span class="keyword">struct<\/span>$/;"	a
+l00395	docs/html/psConstants_8h-source.html	/^<a name="l00395"><\/a><a class="code" href="psConstants_8h.html#a55">00395<\/a> <span class="preprocessor">#define PS_IMAGE_CHECK_SIZE(NAME1, NUM_COLS, NUM_ROWS, RVAL) \\<\/span>$/;"	a
+l00396	docs/html/psFunctions_8h-source.html	/^<a name="l00396"><\/a><a class="code" href="structpsSpline1D.html#o0">00396<\/a>     <a class="code" href="group__DataContainer.html#ga6">psS32<\/a> n;                        <span class="comment">\/\/\/&lt; The number of spline polynomials<\/span>$/;"	a
+l00397	docs/html/psFunctions_8h-source.html	/^<a name="l00397"><\/a><a class="code" href="structpsSpline1D.html#o1">00397<\/a> <span class="comment"><\/span>    <a class="code" href="structpsPolynomial1D.html">psPolynomial1D<\/a> **spline;      <span class="comment">\/\/\/&lt; An array of n pointers to the spline polynomials<\/span>$/;"	a
+l00398	docs/html/psFunctions_8h-source.html	/^<a name="l00398"><\/a><a class="code" href="structpsSpline1D.html#o2">00398<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> *p_psDeriv2;            <span class="comment">\/\/\/&lt; For cubic splines, the second derivative at each domain point.  Size is n+1.<\/span>$/;"	a
+l00399	docs/html/psFunctions_8h-source.html	/^<a name="l00399"><\/a><a class="code" href="structpsSpline1D.html#o3">00399<\/a> <span class="comment"><\/span>    <span class="keywordtype">float<\/span> *domains;               <span class="comment">\/\/\/&lt; The boundaries between each spline piece.  Size is n+1.<\/span>$/;"	a
+l00409	docs/html/psConstants_8h-source.html	/^<a name="l00409"><\/a><a class="code" href="psConstants_8h.html#a56">00409<\/a> <span class="preprocessor">#define PS_READOUT_CHECK_NULL(NAME, RVAL) \\<\/span>$/;"	a
+l00417	docs/html/psConstants_8h-source.html	/^<a name="l00417"><\/a><a class="code" href="psConstants_8h.html#a57">00417<\/a> <span class="preprocessor">#define PS_READOUT_CHECK_EMPTY(NAME, RVAL) \\<\/span>$/;"	a
+l00424	docs/html/psConstants_8h-source.html	/^<a name="l00424"><\/a><a class="code" href="psConstants_8h.html#a58">00424<\/a> <span class="preprocessor">#define PS_READOUT_CHECK_TYPE(NAME, TYPE, RVAL) \\<\/span>$/;"	a
+l00434	docs/html/psConstants_8h-source.html	/^<a name="l00434"><\/a><a class="code" href="psConstants_8h.html#a59">00434<\/a> <span class="preprocessor">#define PS_MAX(A, B) \\<\/span>$/;"	a
+l00437	docs/html/psConstants_8h-source.html	/^<a name="l00437"><\/a><a class="code" href="psConstants_8h.html#a60">00437<\/a> <span class="preprocessor"><\/span><span class="preprocessor">#define PS_MIN(A, B) \\<\/span>$/;"	a
+lapseRate	include/psAstrometry.h	/^    const double lapseRate;            \/\/\/< lapse rate (TLR)$/;"	m
+lapseRate	src/astronomy/psAstrometry.h	/^    const double lapseRate;            \/\/\/< lapse rate (TLR)$/;"	m
+lastDelta	include/psMinimize.h	/^    psF32 lastDelta;                   \/\/\/< The last difference for the fit$/;"	m
+lastDelta	src/dataManip/psMinimize.h	/^    psF32 lastDelta;                   \/\/\/< The last difference for the fit$/;"	m
+lastMemBlockAllocated	src/sysUtils/psMemory.c	/^static psMemBlock* lastMemBlockAllocated = NULL;$/;"	v	file:
+latitude	include/psAstrometry.h	/^    const double latitude;             \/\/\/< Latitude of observatory, east positive (degrees?)$/;"	m
+latitude	include/psAstrometry.h	/^    const double latitude;             \/\/\/< geodetic latitude (radians)$/;"	m
+latitude	src/astronomy/psAstrometry.h	/^    const double latitude;             \/\/\/< Latitude of observatory, east positive (degrees?)$/;"	m
+latitude	src/astronomy/psAstrometry.h	/^    const double latitude;             \/\/\/< geodetic latitude (radians)$/;"	m
+letter_P	docs/html/classes.html	/^<tr><td><a name="letter_P"><\/a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&nbsp;&nbsp;P&nbsp;&nbsp;<\/div><\/td><\/tr><\/table>$/;"	a
+level	include/psTrace.h	/^        psS32 level;                  \/\/ trace level for this component$/;"	m	struct:p_psComponent
+level	src/sysUtils/psTrace.h	/^        psS32 level;                  \/\/ trace level for this component$/;"	m	struct:p_psComponent
+lineno	include/psMemory.h	/^    const psS32 lineno;                  \/\/\/< set from __LINE__ in e.g. p_psAlloc$/;"	m	struct:psMemBlock
+lineno	src/sysUtils/psMemory.h	/^    const psS32 lineno;                  \/\/\/< set from __LINE__ in e.g. p_psAlloc$/;"	m	struct:psMemBlock
+list	include/psList.h	/^psList* list;                      \/\/\/< List iterator to works on$/;"	m
+list	include/psMetadata.h	/^        psList *list;                  \/\/\/< List data.$/;"	m	union:psMetadataItem::<anonymous>
+list	include/psMetadata.h	/^    psList*  list;                     \/\/\/< Metadata in linked-list$/;"	m	struct:psMetadata
+list	src/astronomy/psMetadata.h	/^        psList *list;                  \/\/\/< List data.$/;"	m	union:psMetadataItem::<anonymous>
+list	src/astronomy/psMetadata.h	/^    psList*  list;                     \/\/\/< Metadata in linked-list$/;"	m	struct:psMetadata
+list	src/collections/psList.h	/^psList* list;                      \/\/\/< List iterator to works on$/;"	m
+listFree	src/collections/psList.c	/^static void listFree(psList* list)$/;"	f	file:
+listFree	src/collections/psList.c	/^static void listFree(psList* list);$/;"	p	file:
+listIteratorFree	src/collections/psList.c	/^static void listIteratorFree(psListIterator* iter)$/;"	f	file:
+listIteratorFree	src/collections/psList.c	/^static void listIteratorFree(psListIterator* iter);$/;"	p	file:
+listIteratorRemove	src/collections/psList.c	/^static psBool listIteratorRemove(psListIterator* iterator)$/;"	f	file:
+listIteratorRemove	src/collections/psList.c	/^static psBool listIteratorRemove(psListIterator* iterator);$/;"	p	file:
+lock	include/psList.h	/^    pthread_mutex_t lock;              \/\/\/< mutex to lock a node during changes$/;"	m
+lock	src/collections/psList.h	/^    pthread_mutex_t lock;              \/\/\/< mutex to lock a node during changes$/;"	m
+lockErrorStack	src/sysUtils/psError.c	/^pthread_mutex_t lockErrorStack = PTHREAD_MUTEX_INITIALIZER;$/;"	v
+logDest	src/sysUtils/psLogMsg.c	/^static FILE *logDest = (FILE *) 1;      \/\/ flag to initialize to stderr before using.$/;"	v	file:
+logHost	src/sysUtils/psLogMsg.c	/^static psBool logHost = true;     \/\/ Flag to include host info$/;"	v	file:
+logLevel	src/sysUtils/psLogMsg.c	/^static psBool logLevel = true;    \/\/ Flag to include level info$/;"	v	file:
+logMsg	src/sysUtils/psLogMsg.c	/^static psBool logMsg = true;      \/\/ Flag to include message info$/;"	v	file:
+logName	src/sysUtils/psLogMsg.c	/^static psBool logName = true;     \/\/ Flag to include name info$/;"	v	file:
+logTime	src/sysUtils/psLogMsg.c	/^static psBool logTime = true;     \/\/ Flag to include time info$/;"	v	file:
+longitude	include/psAstrometry.h	/^    const double longitude;            \/\/\/< Longitude of observatory (degrees?)$/;"	m
+longitude	src/astronomy/psAstrometry.h	/^    const double longitude;            \/\/\/< Longitude of observatory (degrees?)$/;"	m
+longitudeOffset	include/psAstrometry.h	/^    const double longitudeOffset;      \/\/\/< longitude + ... (radians)$/;"	m
+longitudeOffset	src/astronomy/psAstrometry.h	/^    const double longitudeOffset;      \/\/\/< longitude + ... (radians)$/;"	m
+lookupTableFree	src/fileUtils/psLookupTable.c	/^static void lookupTableFree(psLookupTable* table)$/;"	f	file:
+lookupTableFree	src/fileUtils/psLookupTable.c	/^static void lookupTableFree(psLookupTable* table);$/;"	p	file:
+lst	include/psAstrometry.h	/^    const double lst;                  \/\/\/< Local Sidereal Time$/;"	m	struct:psExposure
+lst	src/astronomy/psAstrometry.h	/^    const double lst;                  \/\/\/< Local Sidereal Time$/;"	m	struct:psExposure
+main	test/astronomy/tst_psAstrometry.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psAstrometry01.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psCoord.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadataIO.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psMetadata_01.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psMetadata_02.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadata_03.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadata_04.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadata_05.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadata_06.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/astronomy/tst_psMetadata_07.c	/^int main(int argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psTime_01.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psTime_02.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psTime_03.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/astronomy/tst_psTime_04.c	/^int main(int argc, char* argv[])$/;"	f
+main	test/collections/tst_psArray.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psArray01.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psArray02.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/collections/tst_psBitSet.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/collections/tst_psHash00.c	/^psS32 main()$/;"	f
+main	test/collections/tst_psHash01.c	/^psS32 main()$/;"	f
+main	test/collections/tst_psHash02.c	/^psS32 main()$/;"	f
+main	test/collections/tst_psHash03.c	/^psS32 main()$/;"	f
+main	test/collections/tst_psHash04.c	/^psS32 main()$/;"	f
+main	test/collections/tst_psList.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/collections/tst_psScalar.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/collections/tst_psVector.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psVectorSort_01.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psVectorSort_02.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psVectorSort_03.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/collections/tst_psVectorSort_04.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/dataManip/tst_psFunc00.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc01.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc02.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc03.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc04.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc05.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psFunc07.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psHist00.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psHist01.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psHist02.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psHist03.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMatrix01.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/dataManip/tst_psMatrix02.c	/^psS32 main(psS32 argc,$/;"	f
+main	test/dataManip/tst_psMatrix03.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrix04.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrix05.c	/^psS32 main( psS32 argc,$/;"	f
+main	test/dataManip/tst_psMatrix06.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrix07.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/dataManip/tst_psMatrixVectorArithmetic03.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/dataManip/tst_psMinimize00.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize01.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize02.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize03.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize04.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize04_F32.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize04b.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize04b_F32.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize05.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize06.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psMinimize07.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psRandom.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats00.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats01.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats02.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats03.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats04.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats05.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats06.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats07.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats08.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psStats09.c	/^psS32 main()$/;"	f
+main	test/dataManip/tst_psVectorFFT.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/fileUtils/tst_psLookupTable_01.c	/^int main(int argc, char* argv[])$/;"	f
+main	test/image/tst_psImage.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageConvolve.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageExtraction.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/image/tst_psImageFFT.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageIO.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageInterpolate.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageManip.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/image/tst_psImageStats00.c	/^psS32 main()$/;"	f
+main	test/image/tst_psImageStats01.c	/^psS32 main()$/;"	f
+main	test/image/tst_psImageStats02.c	/^psS32 main()$/;"	f
+main	test/image/tst_psImageStats03.c	/^psS32 main()$/;"	f
+main	test/image/tst_psImageStats04.c	/^int main()$/;"	f
+main	test/sysUtils/tst_psAbort.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/sysUtils/tst_psError.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/sysUtils/tst_psLogMsg.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/sysUtils/tst_psMemory.c	/^psS32 main(psS32 argc, char* argv[])$/;"	f
+main	test/sysUtils/tst_psStringCopy.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/sysUtils/tst_psTrace.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+main	test/tst_template.c	/^psS32 main( psS32 argc, char* argv[] )$/;"	f
+makeTestDrivers	test/FullUnitTest	/^sub makeTestDrivers {$/;"	s
+makeTestDrivers	testbin/FullUnitTest	/^sub makeTestDrivers {$/;"	s
+malloc	include/psMemory.h	/^#define malloc(/;"	d
+malloc	src/sysUtils/psMemory.h	/^#define malloc(/;"	d
+mask	include/psAstrometry.h	/^    psImage* mask;                     \/\/\/< Mask area for readout$/;"	m
+mask	include/psFunctions.h	/^    psU8 ****mask;                     \/\/\/< Coefficients mask$/;"	m
+mask	include/psFunctions.h	/^    psU8 ***mask;                      \/\/\/< Coefficient mask$/;"	m
+mask	include/psFunctions.h	/^    psU8 ***mask;                      \/\/\/< Coefficients mask$/;"	m
+mask	include/psFunctions.h	/^    psU8 **mask;                       \/\/\/< Coefficients mask$/;"	m
+mask	include/psFunctions.h	/^    psU8 *mask;                        \/\/\/< Coefficient mask$/;"	m
+mask	src/astronomy/psAstrometry.h	/^    psImage* mask;                     \/\/\/< Mask area for readout$/;"	m
+mask	src/collections/psBitSet.c	/^static char mask(psS32 bit)$/;"	f	file:
+mask	src/dataManip/psFunctions.h	/^    psU8 ****mask;                     \/\/\/< Coefficients mask$/;"	m
+mask	src/dataManip/psFunctions.h	/^    psU8 ***mask;                      \/\/\/< Coefficient mask$/;"	m
+mask	src/dataManip/psFunctions.h	/^    psU8 ***mask;                      \/\/\/< Coefficients mask$/;"	m
+mask	src/dataManip/psFunctions.h	/^    psU8 **mask;                       \/\/\/< Coefficients mask$/;"	m
+mask	src/dataManip/psFunctions.h	/^    psU8 *mask;                        \/\/\/< Coefficient mask$/;"	m
+max	include/psStats.h	/^    psF64 max;                 \/\/\/< maximum data value in array$/;"	m
+max	src/dataManip/psStats.h	/^    psF64 max;                 \/\/\/< maximum data value in array$/;"	m
+maxIter	include/psMinimize.h	/^    psS32 maxIter;                       \/\/\/< Convergence limit$/;"	m
+maxIter	src/dataManip/psMinimize.h	/^    psS32 maxIter;                       \/\/\/< Convergence limit$/;"	m
+maxNum	include/psStats.h	/^    psS32 maxNum;                        \/\/\/< Number above the maximum$/;"	m
+maxNum	src/dataManip/psStats.h	/^    psS32 maxNum;                        \/\/\/< Number above the maximum$/;"	m
+md	include/psMetadata.h	/^        psMetadata *md;                \/\/\/< Metadata data.$/;"	m	union:psMetadataItem::<anonymous>
+md	src/astronomy/psMetadata.h	/^        psMetadata *md;                \/\/\/< Metadata data.$/;"	m	union:psMetadataItem::<anonymous>
+memAllocateCallback	src/sysUtils/psMemory.c	/^static psMemAllocateCallback memAllocateCallback = memAllocateCallbackDefault;$/;"	v	file:
+memAllocateCallback	test/sysUtils/tst_psMemory.c	/^psMemoryId memAllocateCallback( const psMemBlock *ptr )$/;"	f
+memAllocateCallback	test/sysUtils/tst_psMemory.c	/^static psMemoryId memAllocateCallback( const psMemBlock *ptr );$/;"	p	file:
+memAllocateCallbackDefault	src/sysUtils/psMemory.c	/^static psMemoryId memAllocateCallbackDefault(const psMemBlock* ptr)$/;"	f	file:
+memBlockListMutex	src/sysUtils/psMemory.c	/^static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;$/;"	v	file:
+memExhaustedCallback	src/sysUtils/psMemory.c	/^static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;$/;"	v	file:
+memExhaustedCallbackDefault	src/sysUtils/psMemory.c	/^static psPtr memExhaustedCallbackDefault(size_t size)$/;"	f	file:
+memFreeCallback	src/sysUtils/psMemory.c	/^static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;$/;"	v	file:
+memFreeCallback	test/sysUtils/tst_psMemory.c	/^psMemoryId memFreeCallback( const psMemBlock *ptr )$/;"	f
+memFreeCallback	test/sysUtils/tst_psMemory.c	/^static psMemoryId memFreeCallback( const psMemBlock *ptr );$/;"	p	file:
+memFreeCallbackDefault	src/sysUtils/psMemory.c	/^static psMemoryId memFreeCallbackDefault(const psMemBlock* ptr)$/;"	f	file:
+memIdMutex	src/sysUtils/psMemory.c	/^static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;$/;"	v	file:
+memProblemCallback	src/sysUtils/psMemory.c	/^static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;$/;"	v	file:
+memProblemCallback	test/sysUtils/tst_psMemory.c	/^void memProblemCallback( const psMemBlock *ptr, const char *file, psS32 lineno )$/;"	f
+memProblemCallback	test/sysUtils/tst_psMemory.c	/^void memProblemCallback( const psMemBlock *ptr, const char *file, psS32 lineno );$/;"	p	file:
+memProblemCallbackDefault	src/sysUtils/psMemory.c	/^static void memProblemCallbackDefault(const psMemBlock* ptr, const char *file, psS32 lineno)$/;"	f	file:
+memid	src/sysUtils/psMemory.c	/^static psMemoryId memid = 0;$/;"	v	file:
+metadata	include/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< Readout-level metadata$/;"	m
+metadata	include/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< cell-level metadata$/;"	m
+metadata	include/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< chip-level metadata$/;"	m	struct:psChip
+metadata	include/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< focal-plane's metadata$/;"	m	struct:psFPA
+metadata	src/astronomy/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< Readout-level metadata$/;"	m
+metadata	src/astronomy/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< cell-level metadata$/;"	m
+metadata	src/astronomy/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< chip-level metadata$/;"	m	struct:psChip
+metadata	src/astronomy/psAstrometry.h	/^    psMetadata* metadata;              \/\/\/< focal-plane's metadata$/;"	m	struct:psFPA
+metadataFree	src/astronomy/psMetadata.c	/^static void metadataFree(psMetadata* metadata)$/;"	f	file:
+metadataId	src/astronomy/psMetadata.c	/^static psS32 metadataId = 0;$/;"	v	file:
+metadataItemFree	src/astronomy/psMetadata.c	/^static void metadataItemFree(psMetadataItem* metadataItem)$/;"	f	file:
+min	include/psStats.h	/^    psF64 min;                 \/\/\/< minimum data value in array$/;"	m
+min	src/dataManip/psStats.h	/^    psF64 min;                 \/\/\/< minimum data value in array$/;"	m
+minNum	include/psStats.h	/^    psS32 minNum;                        \/\/\/< Number below the minimum$/;"	m
+minNum	src/dataManip/psStats.h	/^    psS32 minNum;                        \/\/\/< Number below the minimum$/;"	m
+msg	include/psError.h	/^    char* msg;                         \/\/\/< the message associated with the error$/;"	m
+msg	src/sysUtils/psError.h	/^    char* msg;                         \/\/\/< the message associated with the error$/;"	m
+myError	src/dataManip/psMinimize.c	/^static psVector *myError;$/;"	v	file:
+myErrorStackPrint	test/sysUtils/tst_psError.c	/^static void myErrorStackPrint(FILE *fd,$/;"	f	file:
+myFunc	test/dataManip/tst_psFunc07.c	/^float myFunc(float x)$/;"	f
+myFunc	test/dataManip/tst_psMinimize00.c	/^float myFunc(const psVector *restrict myData,$/;"	f
+myFunc	test/dataManip/tst_psMinimize01.c	/^float myFunc(const psVector *restrict myData,$/;"	f
+myFunc	test/dataManip/tst_psMinimize02.c	/^float myFunc(const psVector *restrict myParams,$/;"	f
+myFunc	test/dataManip/tst_psMinimize03.c	/^float myFunc(const psVector *restrict myParams,$/;"	f
+myFunc	test/dataManip/tst_psMinimize05.c	/^float myFunc(psVector *myParams,$/;"	f
+myFunc	test/dataManip/tst_psMinimize06.c	/^psVector *myFunc(psImage *myDeriv,$/;"	f
+myFunc0	test/dataManip/tst_psMinimize02.c	/^float myFunc0(const psVector *restrict myParams,$/;"	f
+myFunc0	test/dataManip/tst_psMinimize03.c	/^float myFunc0(const psVector *restrict myParams,$/;"	f
+myFuncDeriv	test/dataManip/tst_psMinimize00.c	/^float myFuncDeriv(const psVector *restrict myData,$/;"	f
+myFuncDeriv	test/dataManip/tst_psMinimize01.c	/^float myFuncDeriv(const psVector *restrict myData,$/;"	f
+myFuncDeriv	test/dataManip/tst_psMinimize02.c	/^float myFuncDeriv(const psVector *restrict myParams,$/;"	f
+myFuncDeriv	test/dataManip/tst_psMinimize03.c	/^float myFuncDeriv(const psVector *restrict myParams,$/;"	f
+myFuncDeriv0	test/dataManip/tst_psMinimize02.c	/^float myFuncDeriv0(const psVector *restrict myParams,$/;"	f
+myFuncDeriv0	test/dataManip/tst_psMinimize03.c	/^float myFuncDeriv0(const psVector *restrict myParams,$/;"	f
+myLogMsg	test/sysUtils/tst_psLogMsg.c	/^static void myLogMsg(const char *name,$/;"	f	file:
+myPowellChi2Func	src/dataManip/psMinimize.c	/^psF32 myPowellChi2Func(const psVector *params,$/;"	f
+myStruct	src/astronomy/psMetadataIO.c	/^myStruct;$/;"	t	file:
+myValue	src/dataManip/psMinimize.c	/^static psVector *myValue;$/;"	v	file:
+n	include/psArray.h	/^    psU32 n;             \/\/\/< Number of elements in use.$/;"	m
+n	include/psBitSet.h	/^    psS32 n;                             \/\/\/< Number of bytes in the array$/;"	m
+n	include/psFunctions.h	/^    psS32 n;                             \/\/\/< Number of terms$/;"	m
+n	include/psFunctions.h	/^    psS32 n;                        \/\/\/< The number of spline polynomials$/;"	m
+n	include/psTrace.h	/^        psS32 n;                      \/\/ number of subcomponents$/;"	m	struct:p_psComponent
+n	include/psVector.h	/^    psU32 n;             \/\/\/< Number of elements in use.$/;"	m
+n	src/collections/psArray.h	/^    psU32 n;             \/\/\/< Number of elements in use.$/;"	m
+n	src/collections/psBitSet.h	/^    psS32 n;                             \/\/\/< Number of bytes in the array$/;"	m
+n	src/collections/psVector.h	/^    psU32 n;             \/\/\/< Number of elements in use.$/;"	m
+n	src/dataManip/psFunctions.h	/^    psS32 n;                             \/\/\/< Number of terms$/;"	m
+n	src/dataManip/psFunctions.h	/^    psS32 n;                        \/\/\/< The number of spline polynomials$/;"	m
+n	src/sysUtils/psTrace.h	/^        psS32 n;                      \/\/ number of subcomponents$/;"	m	struct:p_psComponent
+nW	include/psFunctions.h	/^    psS32 nW;                            \/\/\/< Number of terms in w$/;"	m
+nW	src/dataManip/psFunctions.h	/^    psS32 nW;                            \/\/\/< Number of terms in w$/;"	m
+nX	include/psAstrometry.h	/^    psS32 nX;                            \/\/\/< Number of elements in x direction$/;"	m
+nX	include/psFunctions.h	/^    psS32 nX;                            \/\/\/< Number of terms in x$/;"	m
+nX	src/astronomy/psAstrometry.h	/^    psS32 nX;                            \/\/\/< Number of elements in x direction$/;"	m
+nX	src/dataManip/psFunctions.h	/^    psS32 nX;                            \/\/\/< Number of terms in x$/;"	m
+nY	include/psAstrometry.h	/^    psS32 nY;                            \/\/\/< Number of elements in y direction$/;"	m
+nY	include/psFunctions.h	/^    psS32 nY;                            \/\/\/< Number of terms in y$/;"	m
+nY	src/astronomy/psAstrometry.h	/^    psS32 nY;                            \/\/\/< Number of elements in y direction$/;"	m
+nY	src/dataManip/psFunctions.h	/^    psS32 nY;                            \/\/\/< Number of terms in y$/;"	m
+nZ	include/psFunctions.h	/^    psS32 nZ;                            \/\/\/< Number of terms in z$/;"	m
+nZ	src/dataManip/psFunctions.h	/^    psS32 nZ;                            \/\/\/< Number of terms in z$/;"	m
+nalloc	include/psArray.h	/^    psU32 nalloc;        \/\/\/< Total number of elements available.$/;"	m
+nalloc	include/psVector.h	/^    psU32 nalloc;        \/\/\/< Total number of elements available.$/;"	m
+nalloc	src/collections/psArray.h	/^    psU32 nalloc;        \/\/\/< Total number of elements available.$/;"	m
+nalloc	src/collections/psVector.h	/^    psU32 nalloc;        \/\/\/< Total number of elements available.$/;"	m
+name	include/psAstrometry.h	/^    const char* name;                  \/\/\/< Name of observatory$/;"	m
+name	include/psError.h	/^    char* name;                        \/\/\/< category of code that caused the error$/;"	m
+name	include/psMetadata.h	/^    char *name;                        \/\/\/< Name of metadata item.$/;"	m	struct:psMetadataItem
+name	include/psPhotometry.h	/^    const char *name;           \/\/\/< Name of photometric system$/;"	m
+name	include/psTrace.h	/^        const char *name;           \/\/ last part of name of component$/;"	m	struct:p_psComponent
+name	src/astronomy/psAstrometry.h	/^    const char* name;                  \/\/\/< Name of observatory$/;"	m
+name	src/astronomy/psMetadata.h	/^    char *name;                        \/\/\/< Name of metadata item.$/;"	m	struct:psMetadataItem
+name	src/astronomy/psPhotometry.h	/^    const char *name;           \/\/\/< Name of photometric system$/;"	m
+name	src/sysUtils/psError.h	/^    char* name;                        \/\/\/< category of code that caused the error$/;"	m
+name	src/sysUtils/psTrace.h	/^        const char *name;           \/\/ last part of name of component$/;"	m	struct:p_psComponent
+name	test/collections/tst_psHash01.c	/^    char *name;$/;"	m	file:
+name	test/collections/tst_psHash02.c	/^    char *name;$/;"	m	file:
+name	test/collections/tst_psHash03.c	/^    char *name;$/;"	m	file:
+name	test/collections/tst_psHash04.c	/^    char *name;$/;"	m	file:
+nbucket	include/psHash.h	/^    psS32 nbucket;                \/\/\/< Number of buckets in hash table.$/;"	m	struct:psHash
+nbucket	src/collections/psHash.h	/^    psS32 nbucket;                \/\/\/< Number of buckets in hash table.$/;"	m	struct:psHash
+next	include/psHash.h	/^    struct psHashBucket* next;  \/\/\/< list of other possible keys$/;"	m	struct:psHashBucket
+next	include/psList.h	/^    struct psListElem* next;           \/\/\/< next link in list$/;"	m	struct:psListElem
+next	src/collections/psHash.h	/^    struct psHashBucket* next;  \/\/\/< list of other possible keys$/;"	m	struct:psHashBucket
+next	src/collections/psList.h	/^    struct psListElem* next;           \/\/\/< next link in list$/;"	m	struct:psListElem
+nextBlock	include/psMemory.h	/^    struct psMemBlock* nextBlock;      \/\/\/< next block allocation list$/;"	m	struct:psMemBlock
+nextBlock	src/sysUtils/psMemory.h	/^    struct psMemBlock* nextBlock;      \/\/\/< next block allocation list$/;"	m	struct:psMemBlock
+numCols	include/psImage.h	/^    const psU32 numCols;        \/\/\/< Number of columns in image$/;"	m	struct:psImage
+numCols	include/psLookupTable.h	/^    psU64 numCols;                     \/\/\/< Number of table columns$/;"	m
+numCols	src/fileUtils/psLookupTable.h	/^    psU64 numCols;                     \/\/\/< Number of table columns$/;"	m
+numCols	src/image/psImage.h	/^    const psU32 numCols;        \/\/\/< Number of columns in image$/;"	m	struct:psImage
+numRows	include/psImage.h	/^    const psU32 numRows;        \/\/\/< Number of rows in image.$/;"	m	struct:psImage
+numRows	include/psLookupTable.h	/^    psU64 numRows;                     \/\/\/< Number of table rows$/;"	m
+numRows	src/fileUtils/psLookupTable.h	/^    psU64 numRows;                     \/\/\/< Number of table rows$/;"	m
+numRows	src/image/psImage.h	/^    const psU32 numRows;        \/\/\/< Number of rows in image.$/;"	m	struct:psImage
+nums	include/psStats.h	/^    psVector* nums;                    \/\/\/< Number in each of the bins (INT)$/;"	m
+nums	src/dataManip/psStats.h	/^    psVector* nums;                    \/\/\/< Number in each of the bins (INT)$/;"	m
+o0	docs/html/structp__psComponent.html	/^<a class="anchor" name="o0" doxytag="p_psComponent::name" ><\/a><p>$/;"	a
+o0	docs/html/structpsArray.html	/^<a class="anchor" name="o0" doxytag="psArray::nalloc" ><\/a><p>$/;"	a
+o0	docs/html/structpsBitSet.html	/^<a class="anchor" name="o0" doxytag="psBitSet::n" ><\/a><p>$/;"	a
+o0	docs/html/structpsCell.html	/^<a class="anchor" name="o0" doxytag="psCell::readouts" ><\/a><p>$/;"	a
+o0	docs/html/structpsChip.html	/^<a class="anchor" name="o0" doxytag="psChip::cells" ><\/a><p>$/;"	a
+o0	docs/html/structpsDPolynomial1D.html	/^<a class="anchor" name="o0" doxytag="psDPolynomial1D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o0" doxytag="psDPolynomial2D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o0" doxytag="psDPolynomial3D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o0" doxytag="psDPolynomial4D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsErr.html	/^<a class="anchor" name="o0" doxytag="psErr::name" ><\/a><p>$/;"	a
+o0	docs/html/structpsErrorDescription.html	/^<a class="anchor" name="o0" doxytag="psErrorDescription::code" ><\/a><p>$/;"	a
+o0	docs/html/structpsExposure.html	/^<a class="anchor" name="o0" doxytag="psExposure::ra" ><\/a><p>$/;"	a
+o0	docs/html/structpsFPA.html	/^<a class="anchor" name="o0" doxytag="psFPA::chips" ><\/a><p>$/;"	a
+o0	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o0" doxytag="psFixedPattern::nX" ><\/a><p>$/;"	a
+o0	docs/html/structpsGrommit.html	/^<a class="anchor" name="o0" doxytag="psGrommit::latitude" ><\/a><p>$/;"	a
+o0	docs/html/structpsHash.html	/^<a class="anchor" name="o0" doxytag="psHash::nbucket" ><\/a><p>$/;"	a
+o0	docs/html/structpsHashBucket.html	/^<a class="anchor" name="o0" doxytag="psHashBucket::key" ><\/a><p>$/;"	a
+o0	docs/html/structpsHistogram.html	/^<a class="anchor" name="o0" doxytag="psHistogram::bounds" ><\/a><p>$/;"	a
+o0	docs/html/structpsImage.html	/^<a class="anchor" name="o0" doxytag="psImage::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsKernel.html	/^<a class="anchor" name="o0" doxytag="psKernel::image" ><\/a><p>$/;"	a
+o0	docs/html/structpsList.html	/^<a class="anchor" name="o0" doxytag="psList::size" ><\/a><p>$/;"	a
+o0	docs/html/structpsListElem.html	/^<a class="anchor" name="o0" doxytag="psListElem::prev" ><\/a><p>$/;"	a
+o0	docs/html/structpsListIterator.html	/^<a class="anchor" name="o0" doxytag="psListIterator::list" ><\/a><p>$/;"	a
+o0	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o0" doxytag="psMemBlock::startblock" ><\/a><p>$/;"	a
+o0	docs/html/structpsMetadata.html	/^<a class="anchor" name="o0" doxytag="psMetadata::list" ><\/a><p>$/;"	a
+o0	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o0" doxytag="psMetadataItem::id" ><\/a><p>$/;"	a
+o0	docs/html/structpsMinimization.html	/^<a class="anchor" name="o0" doxytag="psMinimization::maxIter" ><\/a><p>$/;"	a
+o0	docs/html/structpsObservatory.html	/^<a class="anchor" name="o0" doxytag="psObservatory::name" ><\/a><p>$/;"	a
+o0	docs/html/structpsPhotSystem.html	/^<a class="anchor" name="o0" doxytag="psPhotSystem::ID" ><\/a><p>$/;"	a
+o0	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o0" doxytag="psPhotTransform::src" ><\/a><p>$/;"	a
+o0	docs/html/structpsPlane.html	/^<a class="anchor" name="o0" doxytag="psPlane::x" ><\/a><p>$/;"	a
+o0	docs/html/structpsPlaneDistort.html	/^<a class="anchor" name="o0" doxytag="psPlaneDistort::x" ><\/a><p>$/;"	a
+o0	docs/html/structpsPlaneTransform.html	/^<a class="anchor" name="o0" doxytag="psPlaneTransform::x" ><\/a><p>$/;"	a
+o0	docs/html/structpsPolynomial1D.html	/^<a class="anchor" name="o0" doxytag="psPolynomial1D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o0" doxytag="psPolynomial2D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o0" doxytag="psPolynomial3D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o0" doxytag="psPolynomial4D::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsProjection.html	/^<a class="anchor" name="o0" doxytag="psProjection::R" ><\/a><p>$/;"	a
+o0	docs/html/structpsRandom.html	/^<a class="anchor" name="o0" doxytag="psRandom::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsReadout.html	/^<a class="anchor" name="o0" doxytag="psReadout::colBins" ><\/a><p>$/;"	a
+o0	docs/html/structpsRegion.html	/^<a class="anchor" name="o0" doxytag="psRegion::x0" ><\/a><p>$/;"	a
+o0	docs/html/structpsScalar.html	/^<a class="anchor" name="o0" doxytag="psScalar::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsSphere.html	/^<a class="anchor" name="o0" doxytag="psSphere::r" ><\/a><p>$/;"	a
+o0	docs/html/structpsSphereTransform.html	/^<a class="anchor" name="o0" doxytag="psSphereTransform::alphaP" ><\/a><p>$/;"	a
+o0	docs/html/structpsSpline1D.html	/^<a class="anchor" name="o0" doxytag="psSpline1D::n" ><\/a><p>$/;"	a
+o0	docs/html/structpsStats.html	/^<a class="anchor" name="o0" doxytag="psStats::sampleMean" ><\/a><p>$/;"	a
+o0	docs/html/structpsTime.html	/^<a class="anchor" name="o0" doxytag="psTime::sec" ><\/a><p>$/;"	a
+o0	docs/html/structpsType.html	/^<a class="anchor" name="o0" doxytag="psType::type" ><\/a><p>$/;"	a
+o0	docs/html/structpsVector.html	/^<a class="anchor" name="o0" doxytag="psVector::type" ><\/a><p>$/;"	a
+o1	docs/html/structp__psComponent.html	/^<a class="anchor" name="o1" doxytag="p_psComponent::level" ><\/a><p>$/;"	a
+o1	docs/html/structpsArray.html	/^<a class="anchor" name="o1" doxytag="psArray::n" ><\/a><p>$/;"	a
+o1	docs/html/structpsBitSet.html	/^<a class="anchor" name="o1" doxytag="psBitSet::bits" ><\/a><p>$/;"	a
+o1	docs/html/structpsCell.html	/^<a class="anchor" name="o1" doxytag="psCell::metadata" ><\/a><p>$/;"	a
+o1	docs/html/structpsChip.html	/^<a class="anchor" name="o1" doxytag="psChip::metadata" ><\/a><p>$/;"	a
+o1	docs/html/structpsDPolynomial1D.html	/^<a class="anchor" name="o1" doxytag="psDPolynomial1D::n" ><\/a><p>$/;"	a
+o1	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o1" doxytag="psDPolynomial2D::nX" ><\/a><p>$/;"	a
+o1	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o1" doxytag="psDPolynomial3D::nX" ><\/a><p>$/;"	a
+o1	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o1" doxytag="psDPolynomial4D::nW" ><\/a><p>$/;"	a
+o1	docs/html/structpsErr.html	/^<a class="anchor" name="o1" doxytag="psErr::code" ><\/a><p>$/;"	a
+o1	docs/html/structpsErrorDescription.html	/^<a class="anchor" name="o1" doxytag="psErrorDescription::description" ><\/a><p>$/;"	a
+o1	docs/html/structpsExposure.html	/^<a class="anchor" name="o1" doxytag="psExposure::dec" ><\/a><p>$/;"	a
+o1	docs/html/structpsFPA.html	/^<a class="anchor" name="o1" doxytag="psFPA::metadata" ><\/a><p>$/;"	a
+o1	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o1" doxytag="psFixedPattern::nY" ><\/a><p>$/;"	a
+o1	docs/html/structpsGrommit.html	/^<a class="anchor" name="o1" doxytag="psGrommit::sinLat" ><\/a><p>$/;"	a
+o1	docs/html/structpsHash.html	/^<a class="anchor" name="o1" doxytag="psHash::buckets" ><\/a><p>$/;"	a
+o1	docs/html/structpsHashBucket.html	/^<a class="anchor" name="o1" doxytag="psHashBucket::data" ><\/a><p>$/;"	a
+o1	docs/html/structpsHistogram.html	/^<a class="anchor" name="o1" doxytag="psHistogram::nums" ><\/a><p>$/;"	a
+o1	docs/html/structpsImage.html	/^<a class="anchor" name="o1" doxytag="psImage::numCols" ><\/a><p>$/;"	a
+o1	docs/html/structpsKernel.html	/^<a class="anchor" name="o1" doxytag="psKernel::xMin" ><\/a><p>$/;"	a
+o1	docs/html/structpsList.html	/^<a class="anchor" name="o1" doxytag="psList::head" ><\/a><p>$/;"	a
+o1	docs/html/structpsListElem.html	/^<a class="anchor" name="o1" doxytag="psListElem::next" ><\/a><p>$/;"	a
+o1	docs/html/structpsListIterator.html	/^<a class="anchor" name="o1" doxytag="psListIterator::cursor" ><\/a><p>$/;"	a
+o1	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o1" doxytag="psMemBlock::previousBlock" ><\/a><p>$/;"	a
+o1	docs/html/structpsMetadata.html	/^<a class="anchor" name="o1" doxytag="psMetadata::table" ><\/a><p>$/;"	a
+o1	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o1" doxytag="psMetadataItem::name" ><\/a><p>$/;"	a
+o1	docs/html/structpsMinimization.html	/^<a class="anchor" name="o1" doxytag="psMinimization::tol" ><\/a><p>$/;"	a
+o1	docs/html/structpsObservatory.html	/^<a class="anchor" name="o1" doxytag="psObservatory::latitude" ><\/a><p>$/;"	a
+o1	docs/html/structpsPhotSystem.html	/^<a class="anchor" name="o1" doxytag="psPhotSystem::name" ><\/a><p>$/;"	a
+o1	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o1" doxytag="psPhotTransform::dst" ><\/a><p>$/;"	a
+o1	docs/html/structpsPlane.html	/^<a class="anchor" name="o1" doxytag="psPlane::y" ><\/a><p>$/;"	a
+o1	docs/html/structpsPlaneDistort.html	/^<a class="anchor" name="o1" doxytag="psPlaneDistort::y" ><\/a><p>$/;"	a
+o1	docs/html/structpsPlaneTransform.html	/^<a class="anchor" name="o1" doxytag="psPlaneTransform::y" ><\/a><p>$/;"	a
+o1	docs/html/structpsPolynomial1D.html	/^<a class="anchor" name="o1" doxytag="psPolynomial1D::n" ><\/a><p>$/;"	a
+o1	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o1" doxytag="psPolynomial2D::nX" ><\/a><p>$/;"	a
+o1	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o1" doxytag="psPolynomial3D::nX" ><\/a><p>$/;"	a
+o1	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o1" doxytag="psPolynomial4D::nW" ><\/a><p>$/;"	a
+o1	docs/html/structpsProjection.html	/^<a class="anchor" name="o1" doxytag="psProjection::D" ><\/a><p>$/;"	a
+o1	docs/html/structpsRandom.html	/^<a class="anchor" name="o1" doxytag="psRandom::gsl" ><\/a><p>$/;"	a
+o1	docs/html/structpsReadout.html	/^<a class="anchor" name="o1" doxytag="psReadout::rowBins" ><\/a><p>$/;"	a
+o1	docs/html/structpsRegion.html	/^<a class="anchor" name="o1" doxytag="psRegion::x1" ><\/a><p>$/;"	a
+o1	docs/html/structpsScalar.html	/^<a class="anchor" name="o1" doxytag="psScalar::U8" ><\/a><p>$/;"	a
+o1	docs/html/structpsSphere.html	/^<a class="anchor" name="o1" doxytag="psSphere::d" ><\/a><p>$/;"	a
+o1	docs/html/structpsSphereTransform.html	/^<a class="anchor" name="o1" doxytag="psSphereTransform::cosDeltaP" ><\/a><p>$/;"	a
+o1	docs/html/structpsSpline1D.html	/^<a class="anchor" name="o1" doxytag="psSpline1D::spline" ><\/a><p>$/;"	a
+o1	docs/html/structpsStats.html	/^<a class="anchor" name="o1" doxytag="psStats::sampleMedian" ><\/a><p>$/;"	a
+o1	docs/html/structpsTime.html	/^<a class="anchor" name="o1" doxytag="psTime::usec" ><\/a><p>$/;"	a
+o1	docs/html/structpsType.html	/^<a class="anchor" name="o1" doxytag="psType::dimen" ><\/a><p>$/;"	a
+o1	docs/html/structpsVector.html	/^<a class="anchor" name="o1" doxytag="psVector::nalloc" ><\/a><p>$/;"	a
+o10	docs/html/structpsExposure.html	/^<a class="anchor" name="o10" doxytag="psExposure::exposureTime" ><\/a><p>$/;"	a
+o10	docs/html/structpsFPA.html	/^<a class="anchor" name="o10" doxytag="psFPA::rmsX" ><\/a><p>$/;"	a
+o10	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o10" doxytag="psFixedPattern::x" ><\/a><p>$/;"	a
+o10	docs/html/structpsGrommit.html	/^<a class="anchor" name="o10" doxytag="psGrommit::refractA" ><\/a><p>$/;"	a
+o10	docs/html/structpsImage.html	/^<a class="anchor" name="o10" doxytag="psImage::S16" ><\/a><p>$/;"	a
+o10	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o10" doxytag="psMemBlock::persistent" ><\/a><p>$/;"	a
+o10	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o10" doxytag="psMetadataItem::V" ><\/a><p>$/;"	a
+o10	docs/html/structpsScalar.html	/^<a class="anchor" name="o10" doxytag="psScalar::F64" ><\/a><p>$/;"	a
+o10	docs/html/structpsStats.html	/^<a class="anchor" name="o10" doxytag="psStats::robustLQ" ><\/a><p>$/;"	a
+o10	docs/html/structpsVector.html	/^<a class="anchor" name="o10" doxytag="psVector::S64" ><\/a><p>$/;"	a
+o11	docs/html/structpsExposure.html	/^<a class="anchor" name="o11" doxytag="psExposure::wavelength" ><\/a><p>$/;"	a
+o11	docs/html/structpsFPA.html	/^<a class="anchor" name="o11" doxytag="psFPA::rmsY" ><\/a><p>$/;"	a
+o11	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o11" doxytag="psFixedPattern::y" ><\/a><p>$/;"	a
+o11	docs/html/structpsGrommit.html	/^<a class="anchor" name="o11" doxytag="psGrommit::refractB" ><\/a><p>$/;"	a
+o11	docs/html/structpsImage.html	/^<a class="anchor" name="o11" doxytag="psImage::S32" ><\/a><p>$/;"	a
+o11	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o11" doxytag="psMemBlock::endblock" ><\/a><p>$/;"	a
+o11	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o11" doxytag="psMetadataItem::data" ><\/a><p>$/;"	a
+o11	docs/html/structpsScalar.html	/^<a class="anchor" name="o11" doxytag="psScalar::C32" ><\/a><p>$/;"	a
+o11	docs/html/structpsStats.html	/^<a class="anchor" name="o11" doxytag="psStats::robustN50" ><\/a><p>$/;"	a
+o11	docs/html/structpsVector.html	/^<a class="anchor" name="o11" doxytag="psVector::F32" ><\/a><p>$/;"	a
+o12	docs/html/structpsExposure.html	/^<a class="anchor" name="o12" doxytag="psExposure::observatory" ><\/a><p>$/;"	a
+o12	docs/html/structpsFPA.html	/^<a class="anchor" name="o12" doxytag="psFPA::chi2" ><\/a><p>$/;"	a
+o12	docs/html/structpsGrommit.html	/^<a class="anchor" name="o12" doxytag="psGrommit::longitudeOffset" ><\/a><p>$/;"	a
+o12	docs/html/structpsImage.html	/^<a class="anchor" name="o12" doxytag="psImage::S64" ><\/a><p>$/;"	a
+o12	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o12" doxytag="psMetadataItem::comment" ><\/a><p>$/;"	a
+o12	docs/html/structpsScalar.html	/^<a class="anchor" name="o12" doxytag="psScalar::C64" ><\/a><p>$/;"	a
+o12	docs/html/structpsStats.html	/^<a class="anchor" name="o12" doxytag="psStats::robustNfit" ><\/a><p>$/;"	a
+o12	docs/html/structpsVector.html	/^<a class="anchor" name="o12" doxytag="psVector::F64" ><\/a><p>$/;"	a
+o13	docs/html/structpsExposure.html	/^<a class="anchor" name="o13" doxytag="psExposure::lst" ><\/a><p>$/;"	a
+o13	docs/html/structpsGrommit.html	/^<a class="anchor" name="o13" doxytag="psGrommit::siderealTime" ><\/a><p>$/;"	a
+o13	docs/html/structpsImage.html	/^<a class="anchor" name="o13" doxytag="psImage::F32" ><\/a><p>$/;"	a
+o13	docs/html/structpsScalar.html	/^<a class="anchor" name="o13" doxytag="psScalar::data" ><\/a><p>$/;"	a
+o13	docs/html/structpsStats.html	/^<a class="anchor" name="o13" doxytag="psStats::clippedMean" ><\/a><p>$/;"	a
+o13	docs/html/structpsVector.html	/^<a class="anchor" name="o13" doxytag="psVector::C32" ><\/a><p>$/;"	a
+o14	docs/html/structpsExposure.html	/^<a class="anchor" name="o14" doxytag="psExposure::positionAngle" ><\/a><p>$/;"	a
+o14	docs/html/structpsImage.html	/^<a class="anchor" name="o14" doxytag="psImage::F64" ><\/a><p>$/;"	a
+o14	docs/html/structpsStats.html	/^<a class="anchor" name="o14" doxytag="psStats::clippedStdev" ><\/a><p>$/;"	a
+o14	docs/html/structpsVector.html	/^<a class="anchor" name="o14" doxytag="psVector::C64" ><\/a><p>$/;"	a
+o15	docs/html/structpsExposure.html	/^<a class="anchor" name="o15" doxytag="psExposure::parallacticAngle" ><\/a><p>$/;"	a
+o15	docs/html/structpsImage.html	/^<a class="anchor" name="o15" doxytag="psImage::C32" ><\/a><p>$/;"	a
+o15	docs/html/structpsStats.html	/^<a class="anchor" name="o15" doxytag="psStats::clippedNvalues" ><\/a><p>$/;"	a
+o15	docs/html/structpsVector.html	/^<a class="anchor" name="o15" doxytag="psVector::V" ><\/a><p>$/;"	a
+o16	docs/html/structpsExposure.html	/^<a class="anchor" name="o16" doxytag="psExposure::airmass" ><\/a><p>$/;"	a
+o16	docs/html/structpsImage.html	/^<a class="anchor" name="o16" doxytag="psImage::C64" ><\/a><p>$/;"	a
+o16	docs/html/structpsStats.html	/^<a class="anchor" name="o16" doxytag="psStats::clipSigma" ><\/a><p>$/;"	a
+o16	docs/html/structpsVector.html	/^<a class="anchor" name="o16" doxytag="psVector::data" ><\/a><p>$/;"	a
+o17	docs/html/structpsExposure.html	/^<a class="anchor" name="o17" doxytag="psExposure::parallacticFactor" ><\/a><p>$/;"	a
+o17	docs/html/structpsImage.html	/^<a class="anchor" name="o17" doxytag="psImage::PTR" ><\/a><p>$/;"	a
+o17	docs/html/structpsStats.html	/^<a class="anchor" name="o17" doxytag="psStats::clipIter" ><\/a><p>$/;"	a
+o18	docs/html/structpsExposure.html	/^<a class="anchor" name="o18" doxytag="psExposure::cameraName" ><\/a><p>$/;"	a
+o18	docs/html/structpsImage.html	/^<a class="anchor" name="o18" doxytag="psImage::V" ><\/a><p>$/;"	a
+o18	docs/html/structpsStats.html	/^<a class="anchor" name="o18" doxytag="psStats::min" ><\/a><p>$/;"	a
+o19	docs/html/structpsExposure.html	/^<a class="anchor" name="o19" doxytag="psExposure::telescopeName" ><\/a><p>$/;"	a
+o19	docs/html/structpsImage.html	/^<a class="anchor" name="o19" doxytag="psImage::data" ><\/a><p>$/;"	a
+o19	docs/html/structpsStats.html	/^<a class="anchor" name="o19" doxytag="psStats::max" ><\/a><p>$/;"	a
+o2	docs/html/structp__psComponent.html	/^<a class="anchor" name="o2" doxytag="p_psComponent::p_psSpecified" ><\/a><p>$/;"	a
+o2	docs/html/structpsArray.html	/^<a class="anchor" name="o2" doxytag="psArray::data" ><\/a><p>$/;"	a
+o2	docs/html/structpsCell.html	/^<a class="anchor" name="o2" doxytag="psCell::toChip" ><\/a><p>$/;"	a
+o2	docs/html/structpsChip.html	/^<a class="anchor" name="o2" doxytag="psChip::toFPA" ><\/a><p>$/;"	a
+o2	docs/html/structpsDPolynomial1D.html	/^<a class="anchor" name="o2" doxytag="psDPolynomial1D::coeff" ><\/a><p>$/;"	a
+o2	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o2" doxytag="psDPolynomial2D::nY" ><\/a><p>$/;"	a
+o2	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o2" doxytag="psDPolynomial3D::nY" ><\/a><p>$/;"	a
+o2	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o2" doxytag="psDPolynomial4D::nX" ><\/a><p>$/;"	a
+o2	docs/html/structpsErr.html	/^<a class="anchor" name="o2" doxytag="psErr::msg" ><\/a><p>$/;"	a
+o2	docs/html/structpsExposure.html	/^<a class="anchor" name="o2" doxytag="psExposure::hourAngle" ><\/a><p>$/;"	a
+o2	docs/html/structpsFPA.html	/^<a class="anchor" name="o2" doxytag="psFPA::fromTangentPlane" ><\/a><p>$/;"	a
+o2	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o2" doxytag="psFixedPattern::x0" ><\/a><p>$/;"	a
+o2	docs/html/structpsGrommit.html	/^<a class="anchor" name="o2" doxytag="psGrommit::cosLat" ><\/a><p>$/;"	a
+o2	docs/html/structpsHashBucket.html	/^<a class="anchor" name="o2" doxytag="psHashBucket::next" ><\/a><p>$/;"	a
+o2	docs/html/structpsHistogram.html	/^<a class="anchor" name="o2" doxytag="psHistogram::minNum" ><\/a><p>$/;"	a
+o2	docs/html/structpsImage.html	/^<a class="anchor" name="o2" doxytag="psImage::numRows" ><\/a><p>$/;"	a
+o2	docs/html/structpsKernel.html	/^<a class="anchor" name="o2" doxytag="psKernel::yMin" ><\/a><p>$/;"	a
+o2	docs/html/structpsList.html	/^<a class="anchor" name="o2" doxytag="psList::tail" ><\/a><p>$/;"	a
+o2	docs/html/structpsListElem.html	/^<a class="anchor" name="o2" doxytag="psListElem::data" ><\/a><p>$/;"	a
+o2	docs/html/structpsListIterator.html	/^<a class="anchor" name="o2" doxytag="psListIterator::index" ><\/a><p>$/;"	a
+o2	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o2" doxytag="psMemBlock::nextBlock" ><\/a><p>$/;"	a
+o2	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o2" doxytag="psMetadataItem::type" ><\/a><p>$/;"	a
+o2	docs/html/structpsMinimization.html	/^<a class="anchor" name="o2" doxytag="psMinimization::value" ><\/a><p>$/;"	a
+o2	docs/html/structpsObservatory.html	/^<a class="anchor" name="o2" doxytag="psObservatory::longitude" ><\/a><p>$/;"	a
+o2	docs/html/structpsPhotSystem.html	/^<a class="anchor" name="o2" doxytag="psPhotSystem::camera" ><\/a><p>$/;"	a
+o2	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o2" doxytag="psPhotTransform::pP" ><\/a><p>$/;"	a
+o2	docs/html/structpsPlane.html	/^<a class="anchor" name="o2" doxytag="psPlane::xErr" ><\/a><p>$/;"	a
+o2	docs/html/structpsPolynomial1D.html	/^<a class="anchor" name="o2" doxytag="psPolynomial1D::coeff" ><\/a><p>$/;"	a
+o2	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o2" doxytag="psPolynomial2D::nY" ><\/a><p>$/;"	a
+o2	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o2" doxytag="psPolynomial3D::nY" ><\/a><p>$/;"	a
+o2	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o2" doxytag="psPolynomial4D::nX" ><\/a><p>$/;"	a
+o2	docs/html/structpsProjection.html	/^<a class="anchor" name="o2" doxytag="psProjection::Xs" ><\/a><p>$/;"	a
+o2	docs/html/structpsReadout.html	/^<a class="anchor" name="o2" doxytag="psReadout::col0" ><\/a><p>$/;"	a
+o2	docs/html/structpsRegion.html	/^<a class="anchor" name="o2" doxytag="psRegion::y0" ><\/a><p>$/;"	a
+o2	docs/html/structpsScalar.html	/^<a class="anchor" name="o2" doxytag="psScalar::U16" ><\/a><p>$/;"	a
+o2	docs/html/structpsSphere.html	/^<a class="anchor" name="o2" doxytag="psSphere::rErr" ><\/a><p>$/;"	a
+o2	docs/html/structpsSphereTransform.html	/^<a class="anchor" name="o2" doxytag="psSphereTransform::sinDeltaP" ><\/a><p>$/;"	a
+o2	docs/html/structpsSpline1D.html	/^<a class="anchor" name="o2" doxytag="psSpline1D::p_psDeriv2" ><\/a><p>$/;"	a
+o2	docs/html/structpsStats.html	/^<a class="anchor" name="o2" doxytag="psStats::sampleStdev" ><\/a><p>$/;"	a
+o2	docs/html/structpsTime.html	/^<a class="anchor" name="o2" doxytag="psTime::type" ><\/a><p>$/;"	a
+o2	docs/html/structpsVector.html	/^<a class="anchor" name="o2" doxytag="psVector::n" ><\/a><p>$/;"	a
+o20	docs/html/structpsImage.html	/^<a class="anchor" name="o20" doxytag="psImage::parent" ><\/a><p>$/;"	a
+o20	docs/html/structpsStats.html	/^<a class="anchor" name="o20" doxytag="psStats::binsize" ><\/a><p>$/;"	a
+o21	docs/html/structpsImage.html	/^<a class="anchor" name="o21" doxytag="psImage::children" ><\/a><p>$/;"	a
+o21	docs/html/structpsStats.html	/^<a class="anchor" name="o21" doxytag="psStats::options" ><\/a><p>$/;"	a
+o22	docs/html/structpsImage.html	/^<a class="anchor" name="o22" doxytag="psImage::rawDataBuffer" ><\/a><p>$/;"	a
+o3	docs/html/structp__psComponent.html	/^<a class="anchor" name="o3" doxytag="p_psComponent::n" ><\/a><p>$/;"	a
+o3	docs/html/structpsCell.html	/^<a class="anchor" name="o3" doxytag="psCell::fromChip" ><\/a><p>$/;"	a
+o3	docs/html/structpsChip.html	/^<a class="anchor" name="o3" doxytag="psChip::fromFPA" ><\/a><p>$/;"	a
+o3	docs/html/structpsDPolynomial1D.html	/^<a class="anchor" name="o3" doxytag="psDPolynomial1D::coeffErr" ><\/a><p>$/;"	a
+o3	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o3" doxytag="psDPolynomial2D::coeff" ><\/a><p>$/;"	a
+o3	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o3" doxytag="psDPolynomial3D::nZ" ><\/a><p>$/;"	a
+o3	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o3" doxytag="psDPolynomial4D::nY" ><\/a><p>$/;"	a
+o3	docs/html/structpsExposure.html	/^<a class="anchor" name="o3" doxytag="psExposure::zenithDistance" ><\/a><p>$/;"	a
+o3	docs/html/structpsFPA.html	/^<a class="anchor" name="o3" doxytag="psFPA::toTangentPlane" ><\/a><p>$/;"	a
+o3	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o3" doxytag="psFixedPattern::y0" ><\/a><p>$/;"	a
+o3	docs/html/structpsGrommit.html	/^<a class="anchor" name="o3" doxytag="psGrommit::abberationMag" ><\/a><p>$/;"	a
+o3	docs/html/structpsHistogram.html	/^<a class="anchor" name="o3" doxytag="psHistogram::maxNum" ><\/a><p>$/;"	a
+o3	docs/html/structpsImage.html	/^<a class="anchor" name="o3" doxytag="psImage::col0" ><\/a><p>$/;"	a
+o3	docs/html/structpsKernel.html	/^<a class="anchor" name="o3" doxytag="psKernel::xMax" ><\/a><p>$/;"	a
+o3	docs/html/structpsList.html	/^<a class="anchor" name="o3" doxytag="psList::iterators" ><\/a><p>$/;"	a
+o3	docs/html/structpsListIterator.html	/^<a class="anchor" name="o3" doxytag="psListIterator::offEnd" ><\/a><p>$/;"	a
+o3	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o3" doxytag="psMemBlock::freeFcn" ><\/a><p>$/;"	a
+o3	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o3" doxytag="psMetadataItem::pType" ><\/a><p>$/;"	a
+o3	docs/html/structpsMinimization.html	/^<a class="anchor" name="o3" doxytag="psMinimization::iter" ><\/a><p>$/;"	a
+o3	docs/html/structpsObservatory.html	/^<a class="anchor" name="o3" doxytag="psObservatory::height" ><\/a><p>$/;"	a
+o3	docs/html/structpsPhotSystem.html	/^<a class="anchor" name="o3" doxytag="psPhotSystem::filter" ><\/a><p>$/;"	a
+o3	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o3" doxytag="psPhotTransform::pM" ><\/a><p>$/;"	a
+o3	docs/html/structpsPlane.html	/^<a class="anchor" name="o3" doxytag="psPlane::yErr" ><\/a><p>$/;"	a
+o3	docs/html/structpsPolynomial1D.html	/^<a class="anchor" name="o3" doxytag="psPolynomial1D::coeffErr" ><\/a><p>$/;"	a
+o3	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o3" doxytag="psPolynomial2D::coeff" ><\/a><p>$/;"	a
+o3	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o3" doxytag="psPolynomial3D::nZ" ><\/a><p>$/;"	a
+o3	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o3" doxytag="psPolynomial4D::nY" ><\/a><p>$/;"	a
+o3	docs/html/structpsProjection.html	/^<a class="anchor" name="o3" doxytag="psProjection::Ys" ><\/a><p>$/;"	a
+o3	docs/html/structpsReadout.html	/^<a class="anchor" name="o3" doxytag="psReadout::row0" ><\/a><p>$/;"	a
+o3	docs/html/structpsRegion.html	/^<a class="anchor" name="o3" doxytag="psRegion::y1" ><\/a><p>$/;"	a
+o3	docs/html/structpsScalar.html	/^<a class="anchor" name="o3" doxytag="psScalar::U32" ><\/a><p>$/;"	a
+o3	docs/html/structpsSphere.html	/^<a class="anchor" name="o3" doxytag="psSphere::dErr" ><\/a><p>$/;"	a
+o3	docs/html/structpsSphereTransform.html	/^<a class="anchor" name="o3" doxytag="psSphereTransform::phiP" ><\/a><p>$/;"	a
+o3	docs/html/structpsSpline1D.html	/^<a class="anchor" name="o3" doxytag="psSpline1D::domains" ><\/a><p>$/;"	a
+o3	docs/html/structpsStats.html	/^<a class="anchor" name="o3" doxytag="psStats::sampleUQ" ><\/a><p>$/;"	a
+o3	docs/html/structpsVector.html	/^<a class="anchor" name="o3" doxytag="psVector::U8" ><\/a><p>$/;"	a
+o4	docs/html/structp__psComponent.html	/^<a class="anchor" name="o4" doxytag="p_psComponent::subcomp" ><\/a><p>$/;"	a
+o4	docs/html/structpsCell.html	/^<a class="anchor" name="o4" doxytag="psCell::toFPA" ><\/a><p>$/;"	a
+o4	docs/html/structpsChip.html	/^<a class="anchor" name="o4" doxytag="psChip::parent" ><\/a><p>$/;"	a
+o4	docs/html/structpsDPolynomial1D.html	/^<a class="anchor" name="o4" doxytag="psDPolynomial1D::mask" ><\/a><p>$/;"	a
+o4	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o4" doxytag="psDPolynomial2D::coeffErr" ><\/a><p>$/;"	a
+o4	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o4" doxytag="psDPolynomial3D::coeff" ><\/a><p>$/;"	a
+o4	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o4" doxytag="psDPolynomial4D::nZ" ><\/a><p>$/;"	a
+o4	docs/html/structpsExposure.html	/^<a class="anchor" name="o4" doxytag="psExposure::azimuth" ><\/a><p>$/;"	a
+o4	docs/html/structpsFPA.html	/^<a class="anchor" name="o4" doxytag="psFPA::pattern" ><\/a><p>$/;"	a
+o4	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o4" doxytag="psFixedPattern::xScale" ><\/a><p>$/;"	a
+o4	docs/html/structpsGrommit.html	/^<a class="anchor" name="o4" doxytag="psGrommit::height" ><\/a><p>$/;"	a
+o4	docs/html/structpsHistogram.html	/^<a class="anchor" name="o4" doxytag="psHistogram::uniform" ><\/a><p>$/;"	a
+o4	docs/html/structpsImage.html	/^<a class="anchor" name="o4" doxytag="psImage::row0" ><\/a><p>$/;"	a
+o4	docs/html/structpsKernel.html	/^<a class="anchor" name="o4" doxytag="psKernel::yMax" ><\/a><p>$/;"	a
+o4	docs/html/structpsList.html	/^<a class="anchor" name="o4" doxytag="psList::lock" ><\/a><p>$/;"	a
+o4	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o4" doxytag="psMemBlock::userMemorySize" ><\/a><p>$/;"	a
+o4	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o4" doxytag="psMetadataItem::B" ><\/a><p>$/;"	a
+o4	docs/html/structpsMinimization.html	/^<a class="anchor" name="o4" doxytag="psMinimization::lastDelta" ><\/a><p>$/;"	a
+o4	docs/html/structpsObservatory.html	/^<a class="anchor" name="o4" doxytag="psObservatory::tlr" ><\/a><p>$/;"	a
+o4	docs/html/structpsPhotSystem.html	/^<a class="anchor" name="o4" doxytag="psPhotSystem::detector" ><\/a><p>$/;"	a
+o4	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o4" doxytag="psPhotTransform::sP" ><\/a><p>$/;"	a
+o4	docs/html/structpsPolynomial1D.html	/^<a class="anchor" name="o4" doxytag="psPolynomial1D::mask" ><\/a><p>$/;"	a
+o4	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o4" doxytag="psPolynomial2D::coeffErr" ><\/a><p>$/;"	a
+o4	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o4" doxytag="psPolynomial3D::coeff" ><\/a><p>$/;"	a
+o4	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o4" doxytag="psPolynomial4D::nZ" ><\/a><p>$/;"	a
+o4	docs/html/structpsProjection.html	/^<a class="anchor" name="o4" doxytag="psProjection::type" ><\/a><p>$/;"	a
+o4	docs/html/structpsReadout.html	/^<a class="anchor" name="o4" doxytag="psReadout::image" ><\/a><p>$/;"	a
+o4	docs/html/structpsScalar.html	/^<a class="anchor" name="o4" doxytag="psScalar::U64" ><\/a><p>$/;"	a
+o4	docs/html/structpsStats.html	/^<a class="anchor" name="o4" doxytag="psStats::sampleLQ" ><\/a><p>$/;"	a
+o4	docs/html/structpsVector.html	/^<a class="anchor" name="o4" doxytag="psVector::U16" ><\/a><p>$/;"	a
+o5	docs/html/structpsCell.html	/^<a class="anchor" name="o5" doxytag="psCell::toTP" ><\/a><p>$/;"	a
+o5	docs/html/structpsDPolynomial2D.html	/^<a class="anchor" name="o5" doxytag="psDPolynomial2D::mask" ><\/a><p>$/;"	a
+o5	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o5" doxytag="psDPolynomial3D::coeffErr" ><\/a><p>$/;"	a
+o5	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o5" doxytag="psDPolynomial4D::coeff" ><\/a><p>$/;"	a
+o5	docs/html/structpsExposure.html	/^<a class="anchor" name="o5" doxytag="psExposure::time" ><\/a><p>$/;"	a
+o5	docs/html/structpsFPA.html	/^<a class="anchor" name="o5" doxytag="psFPA::exposure" ><\/a><p>$/;"	a
+o5	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o5" doxytag="psFixedPattern::yScale" ><\/a><p>$/;"	a
+o5	docs/html/structpsGrommit.html	/^<a class="anchor" name="o5" doxytag="psGrommit::temperature" ><\/a><p>$/;"	a
+o5	docs/html/structpsImage.html	/^<a class="anchor" name="o5" doxytag="psImage::U8" ><\/a><p>$/;"	a
+o5	docs/html/structpsKernel.html	/^<a class="anchor" name="o5" doxytag="psKernel::kernel" ><\/a><p>$/;"	a
+o5	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o5" doxytag="psMemBlock::id" ><\/a><p>$/;"	a
+o5	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o5" doxytag="psMetadataItem::S32" ><\/a><p>$/;"	a
+o5	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o5" doxytag="psPhotTransform::sM" ><\/a><p>$/;"	a
+o5	docs/html/structpsPolynomial2D.html	/^<a class="anchor" name="o5" doxytag="psPolynomial2D::mask" ><\/a><p>$/;"	a
+o5	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o5" doxytag="psPolynomial3D::coeffErr" ><\/a><p>$/;"	a
+o5	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o5" doxytag="psPolynomial4D::coeff" ><\/a><p>$/;"	a
+o5	docs/html/structpsReadout.html	/^<a class="anchor" name="o5" doxytag="psReadout::mask" ><\/a><p>$/;"	a
+o5	docs/html/structpsScalar.html	/^<a class="anchor" name="o5" doxytag="psScalar::S8" ><\/a><p>$/;"	a
+o5	docs/html/structpsStats.html	/^<a class="anchor" name="o5" doxytag="psStats::robustMean" ><\/a><p>$/;"	a
+o5	docs/html/structpsVector.html	/^<a class="anchor" name="o5" doxytag="psVector::U32" ><\/a><p>$/;"	a
+o6	docs/html/structpsCell.html	/^<a class="anchor" name="o6" doxytag="psCell::toSky" ><\/a><p>$/;"	a
+o6	docs/html/structpsDPolynomial3D.html	/^<a class="anchor" name="o6" doxytag="psDPolynomial3D::mask" ><\/a><p>$/;"	a
+o6	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o6" doxytag="psDPolynomial4D::coeffErr" ><\/a><p>$/;"	a
+o6	docs/html/structpsExposure.html	/^<a class="anchor" name="o6" doxytag="psExposure::rotAngle" ><\/a><p>$/;"	a
+o6	docs/html/structpsFPA.html	/^<a class="anchor" name="o6" doxytag="psFPA::grommit" ><\/a><p>$/;"	a
+o6	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o6" doxytag="psFixedPattern::p_ps_xRows" ><\/a><p>$/;"	a
+o6	docs/html/structpsGrommit.html	/^<a class="anchor" name="o6" doxytag="psGrommit::pressure" ><\/a><p>$/;"	a
+o6	docs/html/structpsImage.html	/^<a class="anchor" name="o6" doxytag="psImage::U16" ><\/a><p>$/;"	a
+o6	docs/html/structpsKernel.html	/^<a class="anchor" name="o6" doxytag="psKernel::p_kernelRows" ><\/a><p>$/;"	a
+o6	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o6" doxytag="psMemBlock::file" ><\/a><p>$/;"	a
+o6	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o6" doxytag="psMetadataItem::F32" ><\/a><p>$/;"	a
+o6	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o6" doxytag="psPhotTransform::pA" ><\/a><p>$/;"	a
+o6	docs/html/structpsPolynomial3D.html	/^<a class="anchor" name="o6" doxytag="psPolynomial3D::mask" ><\/a><p>$/;"	a
+o6	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o6" doxytag="psPolynomial4D::coeffErr" ><\/a><p>$/;"	a
+o6	docs/html/structpsReadout.html	/^<a class="anchor" name="o6" doxytag="psReadout::objects" ><\/a><p>$/;"	a
+o6	docs/html/structpsScalar.html	/^<a class="anchor" name="o6" doxytag="psScalar::S16" ><\/a><p>$/;"	a
+o6	docs/html/structpsStats.html	/^<a class="anchor" name="o6" doxytag="psStats::robustMedian" ><\/a><p>$/;"	a
+o6	docs/html/structpsVector.html	/^<a class="anchor" name="o6" doxytag="psVector::U64" ><\/a><p>$/;"	a
+o7	docs/html/structpsCell.html	/^<a class="anchor" name="o7" doxytag="psCell::parent" ><\/a><p>$/;"	a
+o7	docs/html/structpsDPolynomial4D.html	/^<a class="anchor" name="o7" doxytag="psDPolynomial4D::mask" ><\/a><p>$/;"	a
+o7	docs/html/structpsExposure.html	/^<a class="anchor" name="o7" doxytag="psExposure::temperature" ><\/a><p>$/;"	a
+o7	docs/html/structpsFPA.html	/^<a class="anchor" name="o7" doxytag="psFPA::colorPlus" ><\/a><p>$/;"	a
+o7	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o7" doxytag="psFixedPattern::p_ps_xCols" ><\/a><p>$/;"	a
+o7	docs/html/structpsGrommit.html	/^<a class="anchor" name="o7" doxytag="psGrommit::humidity" ><\/a><p>$/;"	a
+o7	docs/html/structpsImage.html	/^<a class="anchor" name="o7" doxytag="psImage::U32" ><\/a><p>$/;"	a
+o7	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o7" doxytag="psMemBlock::lineno" ><\/a><p>$/;"	a
+o7	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o7" doxytag="psMetadataItem::F64" ><\/a><p>$/;"	a
+o7	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o7" doxytag="psPhotTransform::sA" ><\/a><p>$/;"	a
+o7	docs/html/structpsPolynomial4D.html	/^<a class="anchor" name="o7" doxytag="psPolynomial4D::mask" ><\/a><p>$/;"	a
+o7	docs/html/structpsReadout.html	/^<a class="anchor" name="o7" doxytag="psReadout::metadata" ><\/a><p>$/;"	a
+o7	docs/html/structpsScalar.html	/^<a class="anchor" name="o7" doxytag="psScalar::S32" ><\/a><p>$/;"	a
+o7	docs/html/structpsStats.html	/^<a class="anchor" name="o7" doxytag="psStats::robustMode" ><\/a><p>$/;"	a
+o7	docs/html/structpsVector.html	/^<a class="anchor" name="o7" doxytag="psVector::S8" ><\/a><p>$/;"	a
+o8	docs/html/structpsExposure.html	/^<a class="anchor" name="o8" doxytag="psExposure::pressure" ><\/a><p>$/;"	a
+o8	docs/html/structpsFPA.html	/^<a class="anchor" name="o8" doxytag="psFPA::colorMinus" ><\/a><p>$/;"	a
+o8	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o8" doxytag="psFixedPattern::p_ps_yRows" ><\/a><p>$/;"	a
+o8	docs/html/structpsGrommit.html	/^<a class="anchor" name="o8" doxytag="psGrommit::wavelength" ><\/a><p>$/;"	a
+o8	docs/html/structpsImage.html	/^<a class="anchor" name="o8" doxytag="psImage::U64" ><\/a><p>$/;"	a
+o8	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o8" doxytag="psMemBlock::refCounterMutex" ><\/a><p>$/;"	a
+o8	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o8" doxytag="psMetadataItem::list" ><\/a><p>$/;"	a
+o8	docs/html/structpsPhotTransform.html	/^<a class="anchor" name="o8" doxytag="psPhotTransform::transform" ><\/a><p>$/;"	a
+o8	docs/html/structpsScalar.html	/^<a class="anchor" name="o8" doxytag="psScalar::S64" ><\/a><p>$/;"	a
+o8	docs/html/structpsStats.html	/^<a class="anchor" name="o8" doxytag="psStats::robustStdev" ><\/a><p>$/;"	a
+o8	docs/html/structpsVector.html	/^<a class="anchor" name="o8" doxytag="psVector::S16" ><\/a><p>$/;"	a
+o9	docs/html/structpsExposure.html	/^<a class="anchor" name="o9" doxytag="psExposure::humidity" ><\/a><p>$/;"	a
+o9	docs/html/structpsFPA.html	/^<a class="anchor" name="o9" doxytag="psFPA::projection" ><\/a><p>$/;"	a
+o9	docs/html/structpsFixedPattern.html	/^<a class="anchor" name="o9" doxytag="psFixedPattern::p_ps_yCols" ><\/a><p>$/;"	a
+o9	docs/html/structpsGrommit.html	/^<a class="anchor" name="o9" doxytag="psGrommit::lapseRate" ><\/a><p>$/;"	a
+o9	docs/html/structpsImage.html	/^<a class="anchor" name="o9" doxytag="psImage::S8" ><\/a><p>$/;"	a
+o9	docs/html/structpsMemBlock.html	/^<a class="anchor" name="o9" doxytag="psMemBlock::refCounter" ><\/a><p>$/;"	a
+o9	docs/html/structpsMetadataItem.html	/^<a class="anchor" name="o9" doxytag="psMetadataItem::md" ><\/a><p>$/;"	a
+o9	docs/html/structpsScalar.html	/^<a class="anchor" name="o9" doxytag="psScalar::F32" ><\/a><p>$/;"	a
+o9	docs/html/structpsStats.html	/^<a class="anchor" name="o9" doxytag="psStats::robustUQ" ><\/a><p>$/;"	a
+o9	docs/html/structpsVector.html	/^<a class="anchor" name="o9" doxytag="psVector::S32" ><\/a><p>$/;"	a
+objects	include/psAstrometry.h	/^    psList* objects;                   \/\/\/< Objects derived from Readout$/;"	m
+objects	src/astronomy/psAstrometry.h	/^    psList* objects;                   \/\/\/< Objects derived from Readout$/;"	m
+observatory	include/psAstrometry.h	/^    const psObservatory* observatory;  \/\/\/< Observatory data$/;"	m	struct:psExposure
+observatory	src/astronomy/psAstrometry.h	/^    const psObservatory* observatory;  \/\/\/< Observatory data$/;"	m	struct:psExposure
+observatoryFree	src/astronomy/psAstrometry.c	/^static void observatoryFree(psObservatory* obs)$/;"	f	file:
+offEnd	include/psList.h	/^bool offEnd;                       \/\/\/< Iterator off the end?$/;"	m
+offEnd	src/collections/psList.h	/^bool offEnd;                       \/\/\/< Iterator off the end?$/;"	m
+options	include/psStats.h	/^    psStatsOptions options;     \/\/\/< bitmask of calculated values$/;"	m
+options	src/dataManip/psStats.h	/^    psStatsOptions options;     \/\/\/< bitmask of calculated values$/;"	m
+ordPolynomial1DEval	src/dataManip/psFunctions.c	/^static psF32 ordPolynomial1DEval(psF32 x, const psPolynomial1D* myPoly)$/;"	f	file:
+ordPolynomial2DEval	src/dataManip/psFunctions.c	/^static psF32 ordPolynomial2DEval(psF32 x,$/;"	f	file:
+ordPolynomial3DEval	src/dataManip/psFunctions.c	/^static psF32 ordPolynomial3DEval(psF32 x, psF32 y, psF32 z, const psPolynomial3D* myPoly)$/;"	f	file:
+ordPolynomial4DEval	src/dataManip/psFunctions.c	/^static psF32 ordPolynomial4DEval(psF32 w, psF32 x, psF32 y, psF32 z, const psPolynomial4D* myPoly)$/;"	f	file:
+pA	include/psPhotometry.h	/^    float pA;                   \/\/\/< Color offset for references$/;"	m
+pA	src/astronomy/psPhotometry.h	/^    float pA;                   \/\/\/< Color offset for references$/;"	m
+pM	include/psPhotometry.h	/^    psPhotSystem pM;            \/\/\/< Primary color reference$/;"	m
+pM	src/astronomy/psPhotometry.h	/^    psPhotSystem pM;            \/\/\/< Primary color reference$/;"	m
+pP	include/psPhotometry.h	/^    psPhotSystem pP;            \/\/\/< Primary color reference$/;"	m
+pP	src/astronomy/psPhotometry.h	/^    psPhotSystem pP;            \/\/\/< Primary color reference$/;"	m
+pType	include/psMetadata.h	/^    psElemType pType;                  \/\/\/< Primitive data type$/;"	m	struct:psMetadataItem
+pType	src/astronomy/psMetadata.h	/^    psElemType pType;                  \/\/\/< Primitive data type$/;"	m	struct:psMetadataItem
+p_fd	src/fileUtils/psFits.h	/^    fitsfile* p_fd;                    \/\/\/< the CFITSIO fits files handle.$/;"	m
+p_fftwWisdomImported	src/dataManip/psVectorFFT.c	/^static psBool p_fftwWisdomImported = false;$/;"	v	file:
+p_fftwWisdomImported	src/image/psImageFFT.c	/^static psBool p_fftwWisdomImported = false;$/;"	v	file:
+p_kernelRows	include/psImageConvolve.h	/^    psKernelType** p_kernelRows;       \/\/\/< Pointer to the rows of the kernel data; not intended for user use.$/;"	m
+p_kernelRows	src/image/psImageConvolve.h	/^    psKernelType** p_kernelRows;       \/\/\/< Pointer to the rows of the kernel data; not intended for user use.$/;"	m
+p_printFooter	include/psTest.h	/^void p_printFooter($/;"	p
+p_printFooter	test/psTest.c	/^void p_printFooter( FILE *fp,$/;"	f
+p_printFooter	test/psTest.h	/^void p_printFooter($/;"	p
+p_printNegativeTestHeader	include/psTest.h	/^void p_printNegativeTestHeader($/;"	p
+p_printNegativeTestHeader	test/psTest.c	/^void p_printNegativeTestHeader( FILE *fp,$/;"	f
+p_printNegativeTestHeader	test/psTest.h	/^void p_printNegativeTestHeader($/;"	p
+p_printPositiveTestHeader	include/psTest.h	/^void p_printPositiveTestHeader($/;"	p
+p_printPositiveTestHeader	test/psTest.c	/^void p_printPositiveTestHeader( FILE *fp,$/;"	f
+p_printPositiveTestHeader	test/psTest.h	/^void p_printPositiveTestHeader($/;"	p
+p_ps1DPolyMedian	src/dataManip/psStats.c	/^psF32 p_ps1DPolyMedian(psPolynomial1D* myPoly,$/;"	f
+p_psAlloc	include/psMemory.h	/^psPtr p_psAlloc(size_t size,    \/\/\/< Size required$/;"	p
+p_psAlloc	src/sysUtils/psMemory.c	/^psPtr p_psAlloc(size_t size, const char *file, psS32 lineno)$/;"	f
+p_psAlloc	src/sysUtils/psMemory.h	/^psPtr p_psAlloc(size_t size,    \/\/\/< Size required$/;"	p
+p_psArg	test/astronomy/tst_psCoord.c	/^float p_psArg(float x,$/;"	f
+p_psComponent	include/psTrace.h	/^    typedef struct p_psComponent$/;"	s
+p_psComponent	include/psTrace.h	/^p_psComponent;$/;"	t
+p_psComponent	src/sysUtils/psTrace.h	/^    typedef struct p_psComponent$/;"	s
+p_psComponent	src/sysUtils/psTrace.h	/^p_psComponent;$/;"	t
+p_psConvertToF32	src/dataManip/psStats.c	/^psVector* p_psConvertToF32(psVector* in)$/;"	f
+p_psConvertToF32	src/dataManip/psStats.c	/^psVector* p_psConvertToF32(psVector* in);$/;"	p	file:
+p_psCreateChebyshevPolys	src/image/psImageStats.c	/^psPolynomial1D **p_psCreateChebyshevPolys(psS32 maxChebyPoly)$/;"	f
+p_psDeriv2	include/psFunctions.h	/^    psF32 *p_psDeriv2;            \/\/\/< For cubic splines, the second derivative at each domain point.  Size is n+1.$/;"	m
+p_psDeriv2	src/dataManip/psFunctions.h	/^    psF32 *p_psDeriv2;            \/\/\/< For cubic splines, the second derivative at each domain point.  Size is n+1.$/;"	m
+p_psDetermineBracket	src/dataManip/psMinimize.c	/^psVector *p_psDetermineBracket(psVector *params,$/;"	f
+p_psDetermineBracket2	src/dataManip/psMinimize.c	/^psVector *p_psDetermineBracket2(psVector *params,$/;"	f
+p_psError	include/psError.h	/^psErrorCode p_psError($/;"	p
+p_psError	src/sysUtils/psError.c	/^psErrorCode p_psError(const char* file,$/;"	f
+p_psError	src/sysUtils/psError.h	/^psErrorCode p_psError($/;"	p
+p_psErrorUnregister	include/psErrorCodes.h	/^psBool p_psErrorUnregister($/;"	p
+p_psErrorUnregister	src/sysUtils/psErrorCodes.c	/^psBool p_psErrorUnregister(psErrorCode code)$/;"	f
+p_psErrorUnregister	src/sysUtils/psErrorCodes.h	/^psBool p_psErrorUnregister($/;"	p
+p_psFree	include/psMemory.h	/^void p_psFree($/;"	p
+p_psFree	src/sysUtils/psMemory.c	/^void p_psFree(psPtr vptr, const char *file, psS32 lineno)$/;"	f
+p_psFree	src/sysUtils/psMemory.h	/^void p_psFree($/;"	p
+p_psGaussianDev	include/psFunctions.h	/^psVector* p_psGaussianDev($/;"	p
+p_psGaussianDev	src/dataManip/psFunctions.c	/^psVector* p_psGaussianDev(psF32 mean, psF32 sigma, psS32 Npts)$/;"	f
+p_psGaussianDev	src/dataManip/psFunctions.h	/^psVector* p_psGaussianDev($/;"	p
+p_psGetStatValue	include/psStats.h	/^psBool p_psGetStatValue($/;"	p
+p_psGetStatValue	src/dataManip/psStats.c	/^psBool p_psGetStatValue(const psStats* stats, psF64 *value)$/;"	f
+p_psGetStatValue	src/dataManip/psStats.h	/^psBool p_psGetStatValue($/;"	p
+p_psImageEvalPolynomialCheb	src/image/psImageStats.c	/^psImage* p_psImageEvalPolynomialCheb(psImage* input,$/;"	f
+p_psImageEvalPolynomialOrd	src/image/psImageStats.c	/^psImage* p_psImageEvalPolynomialOrd(psImage* input,$/;"	f
+p_psImagePixelInterpolateComplexFcns	include/psImage.h	/^#define p_psImagePixelInterpolateComplexFcns(/;"	d
+p_psImagePixelInterpolateComplexFcns	src/image/psImage.h	/^#define p_psImagePixelInterpolateComplexFcns(/;"	d
+p_psImagePixelInterpolateFcns	include/psImage.h	/^#define p_psImagePixelInterpolateFcns(/;"	d
+p_psImagePixelInterpolateFcns	src/image/psImage.h	/^#define p_psImagePixelInterpolateFcns(/;"	d
+p_psInitMetadataItemXml	src/astronomy/psMetadataIO.c	/^static void p_psInitMetadataItemXml(void *ctx, char *tagName)$/;"	f	file:
+p_psInitMetadataItemXml	src/astronomy/psMetadataIO.c	/^static void p_psInitMetadataItemXml(void *ctx, char *tagName);$/;"	p	file:
+p_psInitVectorXml	src/astronomy/psMetadataIO.c	/^static void p_psInitVectorXml(void *ctx, char *tagName)$/;"	f	file:
+p_psInitVectorXml	src/astronomy/psMetadataIO.c	/^static void p_psInitVectorXml(void *ctx, char *tagName);$/;"	p	file:
+p_psLineMin	src/dataManip/psMinimize.c	/^psF32 p_psLineMin(psMinimization *min,$/;"	f
+p_psMemAllocateID	src/sysUtils/psMemory.c	/^psMemoryId p_psMemAllocateID = 0;       \/\/ notify user this block is allocated$/;"	v
+p_psMemDecrRefCounter	include/psMemory.h	/^psPtr p_psMemDecrRefCounter($/;"	p
+p_psMemDecrRefCounter	src/sysUtils/psMemory.c	/^psPtr p_psMemDecrRefCounter(psPtr vptr, const char *file, psS32 lineno)$/;"	f
+p_psMemDecrRefCounter	src/sysUtils/psMemory.h	/^psPtr p_psMemDecrRefCounter($/;"	p
+p_psMemFreeID	src/sysUtils/psMemory.c	/^psMemoryId p_psMemFreeID = 0;   \/\/ notify user this block is freed$/;"	v
+p_psMemGetDeallocator	include/psMemory.h	/^psFreeFcn p_psMemGetDeallocator($/;"	p
+p_psMemGetDeallocator	src/sysUtils/psMemory.c	/^psFreeFcn p_psMemGetDeallocator(psPtr vptr)$/;"	f
+p_psMemGetDeallocator	src/sysUtils/psMemory.h	/^psFreeFcn p_psMemGetDeallocator($/;"	p
+p_psMemGetPersistent	include/psMemory.h	/^psBool p_psMemGetPersistent($/;"	p
+p_psMemGetPersistent	src/sysUtils/psMemory.c	/^psBool p_psMemGetPersistent(psPtr vptr)$/;"	f
+p_psMemGetPersistent	src/sysUtils/psMemory.h	/^psBool p_psMemGetPersistent($/;"	p
+p_psMemIncrRefCounter	include/psMemory.h	/^psPtr p_psMemIncrRefCounter($/;"	p
+p_psMemIncrRefCounter	src/sysUtils/psMemory.c	/^psPtr p_psMemIncrRefCounter(psPtr vptr, const char *file, psS32 lineno)$/;"	f
+p_psMemIncrRefCounter	src/sysUtils/psMemory.h	/^psPtr p_psMemIncrRefCounter($/;"	p
+p_psMemSetDeallocator	include/psMemory.h	/^void p_psMemSetDeallocator($/;"	p
+p_psMemSetDeallocator	src/sysUtils/psMemory.c	/^void p_psMemSetDeallocator(psPtr vptr, psFreeFcn freeFcn)$/;"	f
+p_psMemSetDeallocator	src/sysUtils/psMemory.h	/^void p_psMemSetDeallocator($/;"	p
+p_psMemSetPersistent	include/psMemory.h	/^void p_psMemSetPersistent($/;"	p
+p_psMemSetPersistent	src/sysUtils/psMemory.c	/^void p_psMemSetPersistent(psPtr vptr,psBool value)$/;"	f
+p_psMemSetPersistent	src/sysUtils/psMemory.h	/^void p_psMemSetPersistent($/;"	p
+p_psNRSpline1DEval	include/psFunctions.h	/^psF32 p_psNRSpline1DEval(psSpline1D *spline,$/;"	p
+p_psNRSpline1DEval	src/dataManip/psFunctions.h	/^psF32 p_psNRSpline1DEval(psSpline1D *spline,$/;"	p
+p_psNormalizeVectorRangeF32	include/psStats.h	/^void p_psNormalizeVectorRangeF32(psVector* myData, psF32 low, psF32 high);$/;"	p
+p_psNormalizeVectorRangeF32	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeF32(psVector* myData, psF32 low, psF32 high);$/;"	p
+p_psNormalizeVectorRangeF64	include/psStats.h	/^void p_psNormalizeVectorRangeF64(psVector* myData, psF64 low, psF64 high);$/;"	p
+p_psNormalizeVectorRangeF64	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeF64(psVector* myData, psF64 low, psF64 high);$/;"	p
+p_psNormalizeVectorRangeS16	include/psStats.h	/^void p_psNormalizeVectorRangeS16(psVector* myData, psS16 low, psS16 high);$/;"	p
+p_psNormalizeVectorRangeS16	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeS16(psVector* myData, psS16 low, psS16 high);$/;"	p
+p_psNormalizeVectorRangeS32	include/psStats.h	/^void p_psNormalizeVectorRangeS32(psVector* myData, psS32 low, psS32 high);$/;"	p
+p_psNormalizeVectorRangeS32	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeS32(psVector* myData, psS32 low, psS32 high);$/;"	p
+p_psNormalizeVectorRangeS64	include/psStats.h	/^void p_psNormalizeVectorRangeS64(psVector* myData, psS64 low, psS64 high);$/;"	p
+p_psNormalizeVectorRangeS64	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeS64(psVector* myData, psS64 low, psS64 high);$/;"	p
+p_psNormalizeVectorRangeS8	include/psStats.h	/^void p_psNormalizeVectorRangeS8(psVector* myData, psS8 low, psS8 high);$/;"	p
+p_psNormalizeVectorRangeS8	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeS8(psVector* myData, psS8 low, psS8 high);$/;"	p
+p_psNormalizeVectorRangeU16	include/psStats.h	/^void p_psNormalizeVectorRangeU16(psVector* myData, psU16 low, psU16 high);$/;"	p
+p_psNormalizeVectorRangeU16	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeU16(psVector* myData, psU16 low, psU16 high);$/;"	p
+p_psNormalizeVectorRangeU32	include/psStats.h	/^void p_psNormalizeVectorRangeU32(psVector* myData, psU32 low, psU32 high);$/;"	p
+p_psNormalizeVectorRangeU32	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeU32(psVector* myData, psU32 low, psU32 high);$/;"	p
+p_psNormalizeVectorRangeU64	include/psStats.h	/^void p_psNormalizeVectorRangeU64(psVector* myData, psU64 low, psU64 high);$/;"	p
+p_psNormalizeVectorRangeU64	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeU64(psVector* myData, psU64 low, psU64 high);$/;"	p
+p_psNormalizeVectorRangeU8	include/psStats.h	/^void p_psNormalizeVectorRangeU8(psVector* myData, psU8 low, psU8 high);$/;"	p
+p_psNormalizeVectorRangeU8	src/dataManip/psStats.h	/^void p_psNormalizeVectorRangeU8(psVector* myData, psU8 low, psU8 high);$/;"	p
+p_psRealloc	include/psMemory.h	/^psPtr p_psRealloc($/;"	p
+p_psRealloc	src/sysUtils/psMemory.c	/^psPtr p_psRealloc(psPtr vptr, size_t size, const char *file, psS32 lineno)$/;"	f
+p_psRealloc	src/sysUtils/psMemory.h	/^psPtr p_psRealloc($/;"	p
+p_psSpecified	include/psTrace.h	/^        bool p_psSpecified;$/;"	m	struct:p_psComponent
+p_psSpecified	src/sysUtils/psTrace.h	/^        bool p_psSpecified;$/;"	m	struct:p_psComponent
+p_psTimeFinalize	include/psTime.h	/^psBool p_psTimeFinalize(void);$/;"	p
+p_psTimeFinalize	src/astronomy/psTime.c	/^bool p_psTimeFinalize(void)$/;"	f
+p_psTimeFinalize	src/astronomy/psTime.h	/^psBool p_psTimeFinalize(void);$/;"	p
+p_psTimeInit	include/psTime.h	/^psBool p_psTimeInit(const char *fileName);$/;"	p
+p_psTimeInit	src/astronomy/psTime.c	/^bool p_psTimeInit(const char *fileName)$/;"	f
+p_psTimeInit	src/astronomy/psTime.h	/^psBool p_psTimeInit(const char *fileName);$/;"	p
+p_psTrace	include/psTrace.h	/^#        define p_psTrace(/;"	d
+p_psTrace	include/psTrace.h	/^void p_psTrace(const char *facil,       \/\/\/< facilty of interest$/;"	p
+p_psTrace	src/sysUtils/psTrace.c	/^void p_psTrace(const char *comp,        \/\/ component being traced$/;"	f
+p_psTrace	src/sysUtils/psTrace.h	/^#        define p_psTrace(/;"	d
+p_psTrace	src/sysUtils/psTrace.h	/^void p_psTrace(const char *facil,       \/\/\/< facilty of interest$/;"	p
+p_psTraceReset	src/sysUtils/psTrace.c	/^void p_psTraceReset(p_psComponent* currentNode)$/;"	f
+p_psVectorBinDisect	include/psFunctions.h	/^psS32 p_psVectorBinDisect(psVector *bins,$/;"	p
+p_psVectorBinDisect	src/dataManip/psFunctions.h	/^psS32 p_psVectorBinDisect(psVector *bins,$/;"	p
+p_psVectorCheckNonEmpty	src/dataManip/psStats.c	/^bool p_psVectorCheckNonEmpty(const psVector* restrict myVector,$/;"	f
+p_psVectorClippedStats	src/dataManip/psStats.c	/^psS32 p_psVectorClippedStats(const psVector* restrict myVector,$/;"	f
+p_psVectorInterpolate	include/psFunctions.h	/^psScalar *p_psVectorInterpolate(psVector *domain,$/;"	p
+p_psVectorInterpolate	src/dataManip/psFunctions.c	/^psScalar *p_psVectorInterpolate(psVector *domain,$/;"	f
+p_psVectorInterpolate	src/dataManip/psFunctions.h	/^psScalar *p_psVectorInterpolate(psVector *domain,$/;"	p
+p_psVectorMax	src/dataManip/psStats.c	/^psS32 p_psVectorMax(const psVector* restrict myVector,$/;"	f
+p_psVectorMin	src/dataManip/psStats.c	/^psS32 p_psVectorMin(const psVector* restrict myVector,$/;"	f
+p_psVectorNValues	src/dataManip/psStats.c	/^psS32 p_psVectorNValues(const psVector* restrict myVector,$/;"	f
+p_psVectorRobustStats	src/dataManip/psStats.c	/^psS32 p_psVectorRobustStats(const psVector* restrict myVector,$/;"	f
+p_psVectorSampleMean	src/dataManip/psStats.c	/^psS32 p_psVectorSampleMean(const psVector* restrict myVector,$/;"	f
+p_psVectorSampleMedian	src/dataManip/psStats.c	/^bool p_psVectorSampleMedian(const psVector* restrict myVector,$/;"	f
+p_psVectorSampleQuartiles	src/dataManip/psStats.c	/^bool p_psVectorSampleQuartiles(const psVector* restrict myVector,$/;"	f
+p_psVectorSampleStdev	src/dataManip/psStats.c	/^void p_psVectorSampleStdev(const psVector* restrict myVector,$/;"	f
+p_psVectorSampleStdevOLD	src/dataManip/psStats.c	/^void p_psVectorSampleStdevOLD(const psVector* restrict myVector,$/;"	f
+p_psVectorSmoothHistGaussian	src/dataManip/psStats.c	/^psVector* p_psVectorSmoothHistGaussian(psHistogram* robustHistogram,$/;"	f
+p_ps_xCols	include/psAstrometry.h	/^    psS32 p_ps_xCols;                    \/\/\/< Number of cols in the x member$/;"	m
+p_ps_xCols	src/astronomy/psAstrometry.h	/^    psS32 p_ps_xCols;                    \/\/\/< Number of cols in the x member$/;"	m
+p_ps_xRows	include/psAstrometry.h	/^    psS32 p_ps_xRows;                    \/\/\/< Number of rows in the x member$/;"	m
+p_ps_xRows	src/astronomy/psAstrometry.h	/^    psS32 p_ps_xRows;                    \/\/\/< Number of rows in the x member$/;"	m
+p_ps_yCols	include/psAstrometry.h	/^    psS32 p_ps_yCols;                    \/\/\/< Number of cols in the y member$/;"	m
+p_ps_yCols	src/astronomy/psAstrometry.h	/^    psS32 p_ps_yCols;                    \/\/\/< Number of cols in the y member$/;"	m
+p_ps_yRows	include/psAstrometry.h	/^    psS32 p_ps_yRows;                    \/\/\/< Number of rows in the y member$/;"	m
+p_ps_yRows	src/astronomy/psAstrometry.h	/^    psS32 p_ps_yRows;                    \/\/\/< Number of rows in the y member$/;"	m
+p_runTest	include/psTest.h	/^psBool p_runTest($/;"	p
+p_runTest	test/psTest.c	/^psBool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,$/;"	f
+p_runTest	test/psTest.h	/^psBool p_runTest($/;"	p
+p_runTestSuite	include/psTest.h	/^psBool p_runTestSuite($/;"	p
+p_runTestSuite	test/psTest.c	/^psBool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,$/;"	f
+p_runTestSuite	test/psTest.h	/^psBool p_runTestSuite($/;"	p
+p_saxEndElement	src/astronomy/psMetadataIO.c	/^static void p_saxEndElement(void *ctx, const xmlChar *tagName)$/;"	f	file:
+p_saxEndElement	src/astronomy/psMetadataIO.c	/^static void p_saxEndElement(void *ctx, const xmlChar *tagName);$/;"	p	file:
+p_saxStartElement	src/astronomy/psMetadataIO.c	/^static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts)$/;"	f	file:
+p_saxStartElement	src/astronomy/psMetadataIO.c	/^static void p_saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts);$/;"	p	file:
+parallacticAngle	include/psAstrometry.h	/^    const float parallacticAngle;      \/\/\/< Parallactic angle$/;"	m	struct:psExposure
+parallacticAngle	src/astronomy/psAstrometry.h	/^    const float parallacticAngle;      \/\/\/< Parallactic angle$/;"	m	struct:psExposure
+parallacticFactor	include/psAstrometry.h	/^    const float parallacticFactor;     \/\/\/< Parallactic factor$/;"	m	struct:psExposure
+parallacticFactor	src/astronomy/psAstrometry.h	/^    const float parallacticFactor;     \/\/\/< Parallactic factor$/;"	m	struct:psExposure
+parent	include/psAstrometry.h	/^    struct psChip* parent;             \/\/\/< chip in which contains this cell$/;"	m
+parent	include/psAstrometry.h	/^    struct psFPA* parent;              \/\/\/< FPA which contains this chip$/;"	m	struct:psChip
+parent	include/psImage.h	/^    const struct psImage* parent;      \/\/\/< Parent, if a subimage.$/;"	m	struct:psImage
+parent	src/astronomy/psAstrometry.h	/^    struct psChip* parent;             \/\/\/< chip in which contains this cell$/;"	m
+parent	src/astronomy/psAstrometry.h	/^    struct psFPA* parent;              \/\/\/< FPA which contains this chip$/;"	m	struct:psChip
+parent	src/image/psImage.h	/^    const struct psImage* parent;      \/\/\/< Parent, if a subimage.$/;"	m	struct:psImage
+parseBool	src/astronomy/psMetadataIO.c	/^psBool parseBool(char *inString, psS32 *status)$/;"	f
+parseF32	src/fileUtils/psLookupTable.c	/^static psF32 parseF32(char *inString, psParseErrorType *status)$/;"	f	file:
+parseF32	src/fileUtils/psLookupTable.c	/^static psF32 parseF32(char *inString, psParseErrorType *status);$/;"	p	file:
+parseF64	src/fileUtils/psLookupTable.c	/^static psF64 parseF64(char *inString, psParseErrorType *status)$/;"	f	file:
+parseF64	src/fileUtils/psLookupTable.c	/^static psF64 parseF64(char *inString, psParseErrorType *status);$/;"	p	file:
+parseS16	src/fileUtils/psLookupTable.c	/^static psS16 parseS16(char *inString, psParseErrorType *status)$/;"	f	file:
+parseS16	src/fileUtils/psLookupTable.c	/^static psS16 parseS16(char *inString, psParseErrorType *status);$/;"	p	file:
+parseS32	src/fileUtils/psLookupTable.c	/^static psS32 parseS32(char *inString, psParseErrorType *status)$/;"	f	file:
+parseS32	src/fileUtils/psLookupTable.c	/^static psS32 parseS32(char *inString, psParseErrorType *status);$/;"	p	file:
+parseS64	src/fileUtils/psLookupTable.c	/^static psS64 parseS64(char *inString, psParseErrorType *status)$/;"	f	file:
+parseS64	src/fileUtils/psLookupTable.c	/^static psS64 parseS64(char *inString, psParseErrorType *status);$/;"	p	file:
+parseS8	src/fileUtils/psLookupTable.c	/^static psS8 parseS8(char *inString, psParseErrorType *status)$/;"	f	file:
+parseS8	src/fileUtils/psLookupTable.c	/^static psS8 parseS8(char *inString, psParseErrorType *status);$/;"	p	file:
+parseU16	src/fileUtils/psLookupTable.c	/^static psU16 parseU16(char *inString, psParseErrorType *status)$/;"	f	file:
+parseU16	src/fileUtils/psLookupTable.c	/^static psU16 parseU16(char *inString, psParseErrorType *status);$/;"	p	file:
+parseU32	src/fileUtils/psLookupTable.c	/^static psU32 parseU32(char *inString, psParseErrorType *status)$/;"	f	file:
+parseU32	src/fileUtils/psLookupTable.c	/^static psU32 parseU32(char *inString, psParseErrorType *status);$/;"	p	file:
+parseU64	src/fileUtils/psLookupTable.c	/^static psU64 parseU64(char *inString, psParseErrorType *status)$/;"	f	file:
+parseU64	src/fileUtils/psLookupTable.c	/^static psU64 parseU64(char *inString, psParseErrorType *status);$/;"	p	file:
+parseU8	src/fileUtils/psLookupTable.c	/^static psU8 parseU8(char *inString, psParseErrorType *status)$/;"	f	file:
+parseU8	src/fileUtils/psLookupTable.c	/^static psU8 parseU8(char *inString, psParseErrorType *status);$/;"	p	file:
+parseValue	src/astronomy/psMetadataIO.c	/^double parseValue(char *inString, psS32 *status)$/;"	f
+parseValue	src/fileUtils/psLookupTable.c	/^static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status)$/;"	f	file:
+parseValue	src/fileUtils/psLookupTable.c	/^static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);$/;"	p	file:
+parseVector	src/astronomy/psMetadataIO.c	/^psVector* parseVector(char *inString, psElemType elemType, psS32 *status)$/;"	f
+pattern	include/psAstrometry.h	/^    psFixedPattern* pattern;           \/\/\/< fixed pattern residual offsets$/;"	m	struct:psFPA
+pattern	src/astronomy/psAstrometry.h	/^    psFixedPattern* pattern;           \/\/\/< fixed pattern residual offsets$/;"	m	struct:psFPA
+persistent	include/psMemory.h	/^    psBool persistent;                   \/\/\/< marks if this non-user persistent data like error stack, etc.$/;"	m	struct:psMemBlock
+persistent	src/sysUtils/psMemory.h	/^    psBool persistent;                   \/\/\/< marks if this non-user persistent data like error stack, etc.$/;"	m	struct:psMemBlock
+phiP	include/psCoord.h	/^    double phiP;                      \/\/\/< Longitude of the ascending node in the target system$/;"	m
+phiP	src/astronomy/psCoord.h	/^    double phiP;                      \/\/\/< Longitude of the ascending node in the target system$/;"	m
+planeDistortFree	src/astronomy/psCoord.c	/^static void planeDistortFree(psPlaneDistort *pt)$/;"	f	file:
+planeTransformFree	src/astronomy/psCoord.c	/^static void planeTransformFree(psPlaneTransform *pt)$/;"	f	file:
+polynomial1DFree	src/dataManip/psFunctions.c	/^static void polynomial1DFree(psPolynomial1D* myPoly)$/;"	f	file:
+polynomial1DFree	src/dataManip/psFunctions.c	/^static void polynomial1DFree(psPolynomial1D* myPoly);$/;"	p	file:
+polynomial2DFree	src/dataManip/psFunctions.c	/^static void polynomial2DFree(psPolynomial2D* myPoly)$/;"	f	file:
+polynomial2DFree	src/dataManip/psFunctions.c	/^static void polynomial2DFree(psPolynomial2D* myPoly);$/;"	p	file:
+polynomial3DFree	src/dataManip/psFunctions.c	/^static void polynomial3DFree(psPolynomial3D* myPoly)$/;"	f	file:
+polynomial3DFree	src/dataManip/psFunctions.c	/^static void polynomial3DFree(psPolynomial3D* myPoly);$/;"	p	file:
+polynomial4DFree	src/dataManip/psFunctions.c	/^static void polynomial4DFree(psPolynomial4D* myPoly)$/;"	f	file:
+polynomial4DFree	src/dataManip/psFunctions.c	/^static void polynomial4DFree(psPolynomial4D* myPoly);$/;"	p	file:
+positionAngle	include/psAstrometry.h	/^    const float positionAngle;         \/\/\/< Position angle$/;"	m	struct:psExposure
+positionAngle	src/astronomy/psAstrometry.h	/^    const float positionAngle;         \/\/\/< Position angle$/;"	m	struct:psExposure
+pressure	include/psAstrometry.h	/^    const double pressure;             \/\/\/< pressure (PMB)$/;"	m
+pressure	include/psAstrometry.h	/^    const float pressure;              \/\/\/< Air pressure in mB$/;"	m	struct:psExposure
+pressure	src/astronomy/psAstrometry.h	/^    const double pressure;             \/\/\/< pressure (PMB)$/;"	m
+pressure	src/astronomy/psAstrometry.h	/^    const float pressure;              \/\/\/< Air pressure in mB$/;"	m	struct:psExposure
+prev	include/psList.h	/^    struct psListElem* prev;           \/\/\/< previous link in list$/;"	m	struct:psListElem
+prev	src/collections/psList.h	/^    struct psListElem* prev;           \/\/\/< previous link in list$/;"	m	struct:psListElem
+previousBlock	include/psMemory.h	/^    struct psMemBlock* previousBlock;  \/\/\/< previous block in allocation list$/;"	m	struct:psMemBlock
+previousBlock	src/sysUtils/psMemory.h	/^    struct psMemBlock* previousBlock;  \/\/\/< previous block in allocation list$/;"	m	struct:psMemBlock
+printCell	test/astronomy/tst_psAstrometry01.c	/^psS32 printCell(psCell *cell)$/;"	f
+printError	src/fileUtils/psLookupTable.c	/^static psParseErrorType printError(psU64 lineCount, char* badText, psParseErrorType status)$/;"	f	file:
+printFooter	include/psTest.h	/^#define printFooter(/;"	d
+printFooter	test/psTest.h	/^#define printFooter(/;"	d
+printListInt	test/collections/tst_psList.c	/^void printListInt(psList* list)$/;"	f
+printListInt	test/collections/tst_psList.c	/^void printListInt(psList* list);$/;"	p	file:
+printMetadata	test/astronomy/tst_psMetadataIO.c	/^static void printMetadata(psMetadata *metadata)$/;"	f	file:
+printMetadata	test/astronomy/tst_psMetadataIO.c	/^static void printMetadata(psMetadata *metadata);$/;"	p	file:
+printMetadata	test/astronomy/tst_psMetadata_01.c	/^static void printMetadata(psMetadata *metadata)$/;"	f	file:
+printMetadata	test/astronomy/tst_psMetadata_01.c	/^static void printMetadata(psMetadata *metadata);$/;"	p	file:
+printMetadataItem	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);$/;"	p	file:
+printMetadataItem	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);$/;"	p	file:
+printMetadataItem	test/astronomy/tst_psMetadata_02.c	/^static void printMetadataItem(psMetadataItem *metadataItem)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadata_03.c	/^static void printMetadataItem(psMetadataItem *metadataItem)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadata_04.c	/^static void printMetadataItem(psMetadataItem *metadataItem)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadata_05.c	/^static void printMetadataItem(psMetadataItem *metadataItem)$/;"	f	file:
+printMetadataItem	test/astronomy/tst_psMetadata_06.c	/^static void printMetadataItem(psMetadataItem *metadataItem)$/;"	f	file:
+printMetadataList	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataList(psList *metadataItemList, char* spaces)$/;"	f	file:
+printMetadataList	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataList(psList *metadataItemList, char* spaces);$/;"	p	file:
+printMetadataList	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataList(psList *metadataItemList, char* spaces)$/;"	f	file:
+printMetadataList	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataList(psList *metadataItemList, char* spaces);$/;"	p	file:
+printMetadataTable	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataTable(psHash *mdTable)$/;"	f	file:
+printMetadataTable	test/astronomy/tst_psMetadataIO.c	/^static void printMetadataTable(psHash *mdTable);$/;"	p	file:
+printMetadataTable	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataTable(psHash *mdTable)$/;"	f	file:
+printMetadataTable	test/astronomy/tst_psMetadata_01.c	/^static void printMetadataTable(psHash *mdTable);$/;"	p	file:
+printNegativeTestHeader	include/psTest.h	/^#define printNegativeTestHeader(/;"	d
+printNegativeTestHeader	test/psTest.h	/^#define printNegativeTestHeader(/;"	d
+printPositiveTestHeader	include/psTest.h	/^#define printPositiveTestHeader(/;"	d
+printPositiveTestHeader	test/psTest.h	/^#define printPositiveTestHeader(/;"	d
+problemCallbackCalled	test/sysUtils/tst_psMemory.c	/^static psS32 problemCallbackCalled = 0;$/;"	v	file:
+projection	include/psAstrometry.h	/^    psProjection *projection;          \/\/\/< projection$/;"	m	struct:psFPA
+projection	src/astronomy/psAstrometry.h	/^    psProjection *projection;          \/\/\/< projection$/;"	m	struct:psFPA
+psAbort	include/psAbort.h	/^void psAbort($/;"	p
+psAbort	src/sysUtils/psAbort.c	/^void psAbort(const char *name, const char *fmt, ...)$/;"	f
+psAbort	src/sysUtils/psAbort.h	/^void psAbort($/;"	p
+psAlloc	include/psMemory.h	/^#define psAlloc(/;"	d
+psAlloc	include/psMemory.h	/^psPtr psAlloc(size_t size       \/\/\/< Size required$/;"	p
+psAlloc	src/sysUtils/psMemory.h	/^#define psAlloc(/;"	d
+psAlloc	src/sysUtils/psMemory.h	/^psPtr psAlloc(size_t size       \/\/\/< Size required$/;"	p
+psArray	include/psArray.h	/^psArray;$/;"	t
+psArray	src/collections/psArray.h	/^psArray;$/;"	t
+psArrayAdd	include/psArray.h	/^psArray* psArrayAdd($/;"	p
+psArrayAdd	src/collections/psArray.c	/^psArray* psArrayAdd(psArray* psArr,$/;"	f
+psArrayAdd	src/collections/psArray.h	/^psArray* psArrayAdd($/;"	p
+psArrayAlloc	include/psArray.h	/^psArray* psArrayAlloc($/;"	p
+psArrayAlloc	src/collections/psArray.c	/^psArray* psArrayAlloc(psU32 nalloc)$/;"	f
+psArrayAlloc	src/collections/psArray.h	/^psArray* psArrayAlloc($/;"	p
+psArrayElementFree	include/psArray.h	/^void psArrayElementFree($/;"	p
+psArrayElementFree	src/collections/psArray.c	/^void psArrayElementFree(psArray* restrict psArr)$/;"	f
+psArrayElementFree	src/collections/psArray.h	/^void psArrayElementFree($/;"	p
+psArrayRealloc	include/psArray.h	/^psArray* psArrayRealloc($/;"	p
+psArrayRealloc	src/collections/psArray.c	/^psArray* psArrayRealloc(psArray* restrict in, psU32 nalloc)$/;"	f
+psArrayRealloc	src/collections/psArray.h	/^psArray* psArrayRealloc($/;"	p
+psArrayRemove	include/psArray.h	/^psBool psArrayRemove($/;"	p
+psArrayRemove	src/collections/psArray.c	/^psBool psArrayRemove(psArray* psArr,$/;"	f
+psArrayRemove	src/collections/psArray.h	/^psBool psArrayRemove($/;"	p
+psArraySort	include/psArray.h	/^psArray* psArraySort($/;"	p
+psArraySort	src/collections/psArray.c	/^psArray* psArraySort(psArray* in, psComparePtrFcn compare)$/;"	f
+psArraySort	src/collections/psArray.h	/^psArray* psArraySort($/;"	p
+psArrayToList	include/psList.h	/^psList* psArrayToList($/;"	p
+psArrayToList	src/collections/psList.c	/^psList* psArrayToList(psArray* arr)$/;"	f
+psArrayToList	src/collections/psList.h	/^psList* psArrayToList($/;"	p
+psBinaryOp	include/psMatrixVectorArithmetic.h	/^psType* psBinaryOp($/;"	p
+psBinaryOp	src/dataManip/psMatrixVectorArithmetic.c	/^psPtr psBinaryOp(psPtr out, psPtr in1, char *op, psPtr in2)$/;"	f
+psBinaryOp	src/dataManip/psMatrixVectorArithmetic.h	/^psType* psBinaryOp($/;"	p
+psBinaryOp_EXIT	src/dataManip/psMatrixVectorArithmetic.c	/^    #define psBinaryOp_EXIT /;"	d	file:
+psBitSet	include/psBitSet.h	/^psBitSet;$/;"	t
+psBitSet	src/collections/psBitSet.h	/^psBitSet;$/;"	t
+psBitSetAlloc	include/psBitSet.h	/^psBitSet* psBitSetAlloc($/;"	p
+psBitSetAlloc	src/collections/psBitSet.c	/^psBitSet* psBitSetAlloc(psS32 n)$/;"	f
+psBitSetAlloc	src/collections/psBitSet.h	/^psBitSet* psBitSetAlloc($/;"	p
+psBitSetClear	include/psBitSet.h	/^psBitSet* psBitSetClear($/;"	p
+psBitSetClear	src/collections/psBitSet.c	/^psBitSet* psBitSetClear(psBitSet* inBitSet,$/;"	f
+psBitSetClear	src/collections/psBitSet.h	/^psBitSet* psBitSetClear($/;"	p
+psBitSetNot	include/psBitSet.h	/^psBitSet* psBitSetNot($/;"	p
+psBitSetNot	src/collections/psBitSet.c	/^psBitSet* psBitSetNot(psBitSet* outBitSet,$/;"	f
+psBitSetNot	src/collections/psBitSet.h	/^psBitSet* psBitSetNot($/;"	p
+psBitSetOp	include/psBitSet.h	/^psBitSet* psBitSetOp($/;"	p
+psBitSetOp	src/collections/psBitSet.c	/^psBitSet* psBitSetOp(psBitSet* outBitSet,$/;"	f
+psBitSetOp	src/collections/psBitSet.h	/^psBitSet* psBitSetOp($/;"	p
+psBitSetSet	include/psBitSet.h	/^psBitSet* psBitSetSet($/;"	p
+psBitSetSet	src/collections/psBitSet.c	/^psBitSet* psBitSetSet(psBitSet* inBitSet,$/;"	f
+psBitSetSet	src/collections/psBitSet.h	/^psBitSet* psBitSetSet($/;"	p
+psBitSetTest	include/psBitSet.h	/^psBool psBitSetTest($/;"	p
+psBitSetTest	src/collections/psBitSet.c	/^psBool psBitSetTest(const psBitSet* inBitSet,$/;"	f
+psBitSetTest	src/collections/psBitSet.h	/^psBool psBitSetTest($/;"	p
+psBitSetToString	include/psBitSet.h	/^char *psBitSetToString($/;"	p
+psBitSetToString	src/collections/psBitSet.c	/^char *psBitSetToString(const psBitSet* restrict inBitSet)$/;"	f
+psBitSetToString	src/collections/psBitSet.h	/^char *psBitSetToString($/;"	p
+psBool	include/psType.h	/^typedef bool psBool;                   \/\/\/< boolean value$/;"	t
+psBool	src/sysUtils/psType.h	/^typedef bool psBool;                   \/\/\/< boolean value$/;"	t
+psBuildSums1D	src/dataManip/psMinimize.c	/^void psBuildSums1D(psF64 x,$/;"	f
+psC32	include/psType.h	/^typedef float _Complex psC32;          \/\/\/< complex with 32-bit floating point Real and Imagary numbers$/;"	t
+psC32	src/sysUtils/psType.h	/^typedef float _Complex psC32;          \/\/\/< complex with 32-bit floating point Real and Imagary numbers$/;"	t
+psC64	include/psType.h	/^typedef double _Complex psC64;         \/\/\/< complex with 64-bit floating point Real and Imagary numbers$/;"	t
+psC64	src/sysUtils/psType.h	/^typedef double _Complex psC64;         \/\/\/< complex with 64-bit floating point Real and Imagary numbers$/;"	t
+psCell	include/psAstrometry.h	/^psCell;$/;"	t
+psCell	src/astronomy/psAstrometry.h	/^psCell;$/;"	t
+psCellAlloc	include/psAstrometry.h	/^psCell* psCellAlloc($/;"	p
+psCellAlloc	src/astronomy/psAstrometry.c	/^psCell* psCellAlloc(psS32 nReadouts,$/;"	f
+psCellAlloc	src/astronomy/psAstrometry.h	/^psCell* psCellAlloc($/;"	p
+psCellInChip	include/psAstrometry.h	/^psCell* psCellInChip($/;"	p
+psCellInChip	src/astronomy/psAstrometry.c	/^psCell* psCellInChip(const psPlane* chipCoord,$/;"	f
+psCellInChip	src/astronomy/psAstrometry.h	/^psCell* psCellInChip($/;"	p
+psCellInFPA	include/psAstrometry.h	/^psCell* psCellInFPA($/;"	p
+psCellInFPA	src/astronomy/psAstrometry.c	/^psCell* psCellInFPA(const psPlane* fpaCoord,$/;"	f
+psCellInFPA	src/astronomy/psAstrometry.h	/^psCell* psCellInFPA($/;"	p
+psChip	include/psAstrometry.h	/^psChip;$/;"	t
+psChip	include/psAstrometry.h	/^typedef struct psChip$/;"	s
+psChip	src/astronomy/psAstrometry.h	/^psChip;$/;"	t
+psChip	src/astronomy/psAstrometry.h	/^typedef struct psChip$/;"	s
+psChipAlloc	include/psAstrometry.h	/^psChip* psChipAlloc($/;"	p
+psChipAlloc	src/astronomy/psAstrometry.c	/^psChip* psChipAlloc(psS32 nCells,$/;"	f
+psChipAlloc	src/astronomy/psAstrometry.h	/^psChip* psChipAlloc($/;"	p
+psChipInFPA	include/psAstrometry.h	/^psChip* psChipInFPA($/;"	p
+psChipInFPA	src/astronomy/psAstrometry.c	/^psChip* psChipInFPA(const psPlane* fpaCoord,$/;"	f
+psChipInFPA	src/astronomy/psAstrometry.h	/^psChip* psChipInFPA($/;"	p
+psCompareDescendingF32	include/psCompare.h	/^int psCompareDescendingF32($/;"	p
+psCompareDescendingF32	src/collections/psCompare.h	/^int psCompareDescendingF32($/;"	p
+psCompareDescendingF32Ptr	include/psCompare.h	/^int psCompareDescendingF32Ptr($/;"	p
+psCompareDescendingF32Ptr	src/collections/psCompare.h	/^int psCompareDescendingF32Ptr($/;"	p
+psCompareDescendingF64	include/psCompare.h	/^int psCompareDescendingF64($/;"	p
+psCompareDescendingF64	src/collections/psCompare.h	/^int psCompareDescendingF64($/;"	p
+psCompareDescendingF64Ptr	include/psCompare.h	/^int psCompareDescendingF64Ptr($/;"	p
+psCompareDescendingF64Ptr	src/collections/psCompare.h	/^int psCompareDescendingF64Ptr($/;"	p
+psCompareDescendingS16	include/psCompare.h	/^int psCompareDescendingS16($/;"	p
+psCompareDescendingS16	src/collections/psCompare.h	/^int psCompareDescendingS16($/;"	p
+psCompareDescendingS16Ptr	include/psCompare.h	/^int psCompareDescendingS16Ptr($/;"	p
+psCompareDescendingS16Ptr	src/collections/psCompare.h	/^int psCompareDescendingS16Ptr($/;"	p
+psCompareDescendingS32	include/psCompare.h	/^int psCompareDescendingS32($/;"	p
+psCompareDescendingS32	src/collections/psCompare.h	/^int psCompareDescendingS32($/;"	p
+psCompareDescendingS32Ptr	include/psCompare.h	/^int psCompareDescendingS32Ptr($/;"	p
+psCompareDescendingS32Ptr	src/collections/psCompare.h	/^int psCompareDescendingS32Ptr($/;"	p
+psCompareDescendingS64	include/psCompare.h	/^int psCompareDescendingS64($/;"	p
+psCompareDescendingS64	src/collections/psCompare.h	/^int psCompareDescendingS64($/;"	p
+psCompareDescendingS64Ptr	include/psCompare.h	/^int psCompareDescendingS64Ptr($/;"	p
+psCompareDescendingS64Ptr	src/collections/psCompare.h	/^int psCompareDescendingS64Ptr($/;"	p
+psCompareDescendingS8	include/psCompare.h	/^int psCompareDescendingS8($/;"	p
+psCompareDescendingS8	src/collections/psCompare.h	/^int psCompareDescendingS8($/;"	p
+psCompareDescendingS8Ptr	include/psCompare.h	/^int psCompareDescendingS8Ptr($/;"	p
+psCompareDescendingS8Ptr	src/collections/psCompare.h	/^int psCompareDescendingS8Ptr($/;"	p
+psCompareDescendingU16	include/psCompare.h	/^int psCompareDescendingU16($/;"	p
+psCompareDescendingU16	src/collections/psCompare.h	/^int psCompareDescendingU16($/;"	p
+psCompareDescendingU16Ptr	include/psCompare.h	/^int psCompareDescendingU16Ptr($/;"	p
+psCompareDescendingU16Ptr	src/collections/psCompare.h	/^int psCompareDescendingU16Ptr($/;"	p
+psCompareDescendingU32	include/psCompare.h	/^int psCompareDescendingU32($/;"	p
+psCompareDescendingU32	src/collections/psCompare.h	/^int psCompareDescendingU32($/;"	p
+psCompareDescendingU32Ptr	include/psCompare.h	/^int psCompareDescendingU32Ptr($/;"	p
+psCompareDescendingU32Ptr	src/collections/psCompare.h	/^int psCompareDescendingU32Ptr($/;"	p
+psCompareDescendingU64	include/psCompare.h	/^int psCompareDescendingU64($/;"	p
+psCompareDescendingU64	src/collections/psCompare.h	/^int psCompareDescendingU64($/;"	p
+psCompareDescendingU64Ptr	include/psCompare.h	/^int psCompareDescendingU64Ptr($/;"	p
+psCompareDescendingU64Ptr	src/collections/psCompare.h	/^int psCompareDescendingU64Ptr($/;"	p
+psCompareDescendingU8	include/psCompare.h	/^int psCompareDescendingU8($/;"	p
+psCompareDescendingU8	src/collections/psCompare.h	/^int psCompareDescendingU8($/;"	p
+psCompareDescendingU8Ptr	include/psCompare.h	/^int psCompareDescendingU8Ptr($/;"	p
+psCompareDescendingU8Ptr	src/collections/psCompare.h	/^int psCompareDescendingU8Ptr($/;"	p
+psCompareF32	include/psCompare.h	/^int psCompareF32($/;"	p
+psCompareF32	src/collections/psCompare.h	/^int psCompareF32($/;"	p
+psCompareF32Ptr	include/psCompare.h	/^int psCompareF32Ptr($/;"	p
+psCompareF32Ptr	src/collections/psCompare.h	/^int psCompareF32Ptr($/;"	p
+psCompareF64	include/psCompare.h	/^int psCompareF64($/;"	p
+psCompareF64	src/collections/psCompare.h	/^int psCompareF64($/;"	p
+psCompareF64Ptr	include/psCompare.h	/^int psCompareF64Ptr($/;"	p
+psCompareF64Ptr	src/collections/psCompare.h	/^int psCompareF64Ptr($/;"	p
+psCompareFcn	include/psCompare.h	/^typedef int (*psCompareFcn) ($/;"	t
+psCompareFcn	src/collections/psCompare.h	/^typedef int (*psCompareFcn) ($/;"	t
+psComparePtrFcn	include/psCompare.h	/^typedef int (*psComparePtrFcn) ($/;"	t
+psComparePtrFcn	src/collections/psCompare.h	/^typedef int (*psComparePtrFcn) ($/;"	t
+psCompareS16	include/psCompare.h	/^int psCompareS16($/;"	p
+psCompareS16	src/collections/psCompare.h	/^int psCompareS16($/;"	p
+psCompareS16Ptr	include/psCompare.h	/^int psCompareS16Ptr($/;"	p
+psCompareS16Ptr	src/collections/psCompare.h	/^int psCompareS16Ptr($/;"	p
+psCompareS32	include/psCompare.h	/^int psCompareS32($/;"	p
+psCompareS32	src/collections/psCompare.h	/^int psCompareS32($/;"	p
+psCompareS32Ptr	include/psCompare.h	/^int psCompareS32Ptr($/;"	p
+psCompareS32Ptr	src/collections/psCompare.h	/^int psCompareS32Ptr($/;"	p
+psCompareS64	include/psCompare.h	/^int psCompareS64($/;"	p
+psCompareS64	src/collections/psCompare.h	/^int psCompareS64($/;"	p
+psCompareS64Ptr	include/psCompare.h	/^int psCompareS64Ptr($/;"	p
+psCompareS64Ptr	src/collections/psCompare.h	/^int psCompareS64Ptr($/;"	p
+psCompareS8	include/psCompare.h	/^int psCompareS8($/;"	p
+psCompareS8	src/collections/psCompare.h	/^int psCompareS8($/;"	p
+psCompareS8Ptr	include/psCompare.h	/^int psCompareS8Ptr($/;"	p
+psCompareS8Ptr	src/collections/psCompare.h	/^int psCompareS8Ptr($/;"	p
+psCompareU16	include/psCompare.h	/^int psCompareU16($/;"	p
+psCompareU16	src/collections/psCompare.h	/^int psCompareU16($/;"	p
+psCompareU16Ptr	include/psCompare.h	/^int psCompareU16Ptr($/;"	p
+psCompareU16Ptr	src/collections/psCompare.h	/^int psCompareU16Ptr($/;"	p
+psCompareU32	include/psCompare.h	/^int psCompareU32($/;"	p
+psCompareU32	src/collections/psCompare.h	/^int psCompareU32($/;"	p
+psCompareU32Ptr	include/psCompare.h	/^int psCompareU32Ptr($/;"	p
+psCompareU32Ptr	src/collections/psCompare.h	/^int psCompareU32Ptr($/;"	p
+psCompareU64	include/psCompare.h	/^int psCompareU64($/;"	p
+psCompareU64	src/collections/psCompare.h	/^int psCompareU64($/;"	p
+psCompareU64Ptr	include/psCompare.h	/^int psCompareU64Ptr($/;"	p
+psCompareU64Ptr	src/collections/psCompare.h	/^int psCompareU64Ptr($/;"	p
+psCompareU8	include/psCompare.h	/^int psCompareU8($/;"	p
+psCompareU8	src/collections/psCompare.h	/^int psCompareU8($/;"	p
+psCompareU8Ptr	include/psCompare.h	/^int psCompareU8Ptr($/;"	p
+psCompareU8Ptr	src/collections/psCompare.h	/^int psCompareU8Ptr($/;"	p
+psCoordCellToChip	include/psAstrometry.h	/^psPlane* psCoordCellToChip($/;"	p
+psCoordCellToChip	src/astronomy/psAstrometry.c	/^psPlane* psCoordCellToChip(psPlane* outCoord,$/;"	f
+psCoordCellToChip	src/astronomy/psAstrometry.h	/^psPlane* psCoordCellToChip($/;"	p
+psCoordCellToFPA	include/psAstrometry.h	/^psPlane* psCoordCellToFPA($/;"	p
+psCoordCellToFPA	src/astronomy/psAstrometry.c	/^psPlane* psCoordCellToFPA(psPlane* fpaCoord,$/;"	f
+psCoordCellToFPA	src/astronomy/psAstrometry.h	/^psPlane* psCoordCellToFPA($/;"	p
+psCoordCellToSky	include/psAstrometry.h	/^psSphere* psCoordCellToSky($/;"	p
+psCoordCellToSky	src/astronomy/psAstrometry.c	/^psSphere* psCoordCellToSky(psSphere* skyCoord,$/;"	f
+psCoordCellToSky	src/astronomy/psAstrometry.h	/^psSphere* psCoordCellToSky($/;"	p
+psCoordCellToSkyQuick	include/psAstrometry.h	/^psSphere* psCoordCellToSkyQuick($/;"	p
+psCoordCellToSkyQuick	src/astronomy/psAstrometry.c	/^psSphere* psCoordCellToSkyQuick(psSphere* outSphere,$/;"	f
+psCoordCellToSkyQuick	src/astronomy/psAstrometry.h	/^psSphere* psCoordCellToSkyQuick($/;"	p
+psCoordChipToCell	include/psAstrometry.h	/^psPlane* psCoordChipToCell($/;"	p
+psCoordChipToCell	src/astronomy/psAstrometry.c	/^psPlane* psCoordChipToCell(psPlane* cellCoord,$/;"	f
+psCoordChipToCell	src/astronomy/psAstrometry.h	/^psPlane* psCoordChipToCell($/;"	p
+psCoordChipToFPA	include/psAstrometry.h	/^psPlane* psCoordChipToFPA($/;"	p
+psCoordChipToFPA	src/astronomy/psAstrometry.c	/^psPlane* psCoordChipToFPA(psPlane* outCoord,$/;"	f
+psCoordChipToFPA	src/astronomy/psAstrometry.h	/^psPlane* psCoordChipToFPA($/;"	p
+psCoordFPAToChip	include/psAstrometry.h	/^psPlane* psCoordFPAToChip($/;"	p
+psCoordFPAToChip	src/astronomy/psAstrometry.c	/^psPlane* psCoordFPAToChip(psPlane* chipCoord,$/;"	f
+psCoordFPAToChip	src/astronomy/psAstrometry.h	/^psPlane* psCoordFPAToChip($/;"	p
+psCoordFPAToTP	include/psAstrometry.h	/^psPlane* psCoordFPAToTP($/;"	p
+psCoordFPAToTP	src/astronomy/psAstrometry.c	/^psPlane* psCoordFPAToTP(psPlane* outCoord,$/;"	f
+psCoordFPAToTP	src/astronomy/psAstrometry.h	/^psPlane* psCoordFPAToTP($/;"	p
+psCoordSkyToCell	include/psAstrometry.h	/^psPlane* psCoordSkyToCell($/;"	p
+psCoordSkyToCell	src/astronomy/psAstrometry.c	/^psPlane* psCoordSkyToCell(psPlane* cellCoord,$/;"	f
+psCoordSkyToCell	src/astronomy/psAstrometry.h	/^psPlane* psCoordSkyToCell($/;"	p
+psCoordSkyToCellQuick	include/psAstrometry.h	/^psPlane* psCoordSkyToCellQuick($/;"	p
+psCoordSkyToCellQuick	src/astronomy/psAstrometry.c	/^psPlane* psCoordSkyToCellQuick(psPlane* cellCoord,$/;"	f
+psCoordSkyToCellQuick	src/astronomy/psAstrometry.h	/^psPlane* psCoordSkyToCellQuick($/;"	p
+psCoordSkyToTP	include/psAstrometry.h	/^psPlane* psCoordSkyToTP($/;"	p
+psCoordSkyToTP	src/astronomy/psAstrometry.c	/^psPlane* psCoordSkyToTP(psPlane* tpCoord,$/;"	f
+psCoordSkyToTP	src/astronomy/psAstrometry.h	/^psPlane* psCoordSkyToTP($/;"	p
+psCoordTPToFPA	include/psAstrometry.h	/^psPlane* psCoordTPToFPA($/;"	p
+psCoordTPToFPA	src/astronomy/psAstrometry.c	/^psPlane* psCoordTPToFPA(psPlane* fpaCoord,$/;"	f
+psCoordTPToFPA	src/astronomy/psAstrometry.h	/^psPlane* psCoordTPToFPA($/;"	p
+psCoordTPToSky	include/psAstrometry.h	/^psSphere* psCoordTPToSky($/;"	p
+psCoordTPToSky	src/astronomy/psAstrometry.c	/^psSphere* psCoordTPToSky(psSphere* outSphere,$/;"	f
+psCoordTPToSky	src/astronomy/psAstrometry.h	/^psSphere* psCoordTPToSky($/;"	p
+psDPolynomial1D	include/psFunctions.h	/^psDPolynomial1D;$/;"	t
+psDPolynomial1D	src/dataManip/psFunctions.h	/^psDPolynomial1D;$/;"	t
+psDPolynomial1DAlloc	include/psFunctions.h	/^psDPolynomial1D* psDPolynomial1DAlloc($/;"	p
+psDPolynomial1DAlloc	src/dataManip/psFunctions.c	/^psDPolynomial1D* psDPolynomial1DAlloc(psS32 n,$/;"	f
+psDPolynomial1DAlloc	src/dataManip/psFunctions.h	/^psDPolynomial1D* psDPolynomial1DAlloc($/;"	p
+psDPolynomial1DEval	include/psFunctions.h	/^psF64 psDPolynomial1DEval($/;"	p
+psDPolynomial1DEval	src/dataManip/psFunctions.c	/^psF64 psDPolynomial1DEval(const psDPolynomial1D* myPoly, psF64 x)$/;"	f
+psDPolynomial1DEval	src/dataManip/psFunctions.h	/^psF64 psDPolynomial1DEval($/;"	p
+psDPolynomial1DEvalVector	include/psFunctions.h	/^psVector *psDPolynomial1DEvalVector($/;"	p
+psDPolynomial1DEvalVector	src/dataManip/psFunctions.c	/^psVector *psDPolynomial1DEvalVector(const psDPolynomial1D *myPoly,$/;"	f
+psDPolynomial1DEvalVector	src/dataManip/psFunctions.h	/^psVector *psDPolynomial1DEvalVector($/;"	p
+psDPolynomial2D	include/psFunctions.h	/^psDPolynomial2D;$/;"	t
+psDPolynomial2D	src/dataManip/psFunctions.h	/^psDPolynomial2D;$/;"	t
+psDPolynomial2DAlloc	include/psFunctions.h	/^psDPolynomial2D* psDPolynomial2DAlloc($/;"	p
+psDPolynomial2DAlloc	src/dataManip/psFunctions.c	/^psDPolynomial2D* psDPolynomial2DAlloc(psS32 nX, psS32 nY,$/;"	f
+psDPolynomial2DAlloc	src/dataManip/psFunctions.h	/^psDPolynomial2D* psDPolynomial2DAlloc($/;"	p
+psDPolynomial2DEval	include/psFunctions.h	/^psF64 psDPolynomial2DEval($/;"	p
+psDPolynomial2DEval	src/dataManip/psFunctions.c	/^psF64 psDPolynomial2DEval(const psDPolynomial2D* myPoly,$/;"	f
+psDPolynomial2DEval	src/dataManip/psFunctions.h	/^psF64 psDPolynomial2DEval($/;"	p
+psDPolynomial2DEvalVector	include/psFunctions.h	/^psVector *psDPolynomial2DEvalVector($/;"	p
+psDPolynomial2DEvalVector	src/dataManip/psFunctions.c	/^psVector *psDPolynomial2DEvalVector(const psDPolynomial2D *myPoly,$/;"	f
+psDPolynomial2DEvalVector	src/dataManip/psFunctions.h	/^psVector *psDPolynomial2DEvalVector($/;"	p
+psDPolynomial3D	include/psFunctions.h	/^psDPolynomial3D;$/;"	t
+psDPolynomial3D	src/dataManip/psFunctions.h	/^psDPolynomial3D;$/;"	t
+psDPolynomial3DAlloc	include/psFunctions.h	/^psDPolynomial3D* psDPolynomial3DAlloc($/;"	p
+psDPolynomial3DAlloc	src/dataManip/psFunctions.c	/^psDPolynomial3D* psDPolynomial3DAlloc(psS32 nX, psS32 nY, psS32 nZ,$/;"	f
+psDPolynomial3DAlloc	src/dataManip/psFunctions.h	/^psDPolynomial3D* psDPolynomial3DAlloc($/;"	p
+psDPolynomial3DEval	include/psFunctions.h	/^psF64 psDPolynomial3DEval($/;"	p
+psDPolynomial3DEval	src/dataManip/psFunctions.c	/^psF64 psDPolynomial3DEval(const psDPolynomial3D* myPoly,$/;"	f
+psDPolynomial3DEval	src/dataManip/psFunctions.h	/^psF64 psDPolynomial3DEval($/;"	p
+psDPolynomial3DEvalVector	include/psFunctions.h	/^psVector *psDPolynomial3DEvalVector($/;"	p
+psDPolynomial3DEvalVector	src/dataManip/psFunctions.c	/^psVector *psDPolynomial3DEvalVector(const psDPolynomial3D *myPoly,$/;"	f
+psDPolynomial3DEvalVector	src/dataManip/psFunctions.h	/^psVector *psDPolynomial3DEvalVector($/;"	p
+psDPolynomial4D	include/psFunctions.h	/^psDPolynomial4D;$/;"	t
+psDPolynomial4D	src/dataManip/psFunctions.h	/^psDPolynomial4D;$/;"	t
+psDPolynomial4DAlloc	include/psFunctions.h	/^psDPolynomial4D* psDPolynomial4DAlloc($/;"	p
+psDPolynomial4DAlloc	src/dataManip/psFunctions.c	/^psDPolynomial4D* psDPolynomial4DAlloc(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,$/;"	f
+psDPolynomial4DAlloc	src/dataManip/psFunctions.h	/^psDPolynomial4D* psDPolynomial4DAlloc($/;"	p
+psDPolynomial4DEval	include/psFunctions.h	/^psF64 psDPolynomial4DEval($/;"	p
+psDPolynomial4DEval	src/dataManip/psFunctions.c	/^psF64 psDPolynomial4DEval(const psDPolynomial4D* myPoly,$/;"	f
+psDPolynomial4DEval	src/dataManip/psFunctions.h	/^psF64 psDPolynomial4DEval($/;"	p
+psDPolynomial4DEvalVector	include/psFunctions.h	/^psVector *psDPolynomial4DEvalVector($/;"	p
+psDPolynomial4DEvalVector	src/dataManip/psFunctions.c	/^psVector *psDPolynomial4DEvalVector(const psDPolynomial4D *myPoly,$/;"	f
+psDPolynomial4DEvalVector	src/dataManip/psFunctions.h	/^psVector *psDPolynomial4DEvalVector($/;"	p
+psDeproject	include/psCoord.h	/^psSphere* psDeproject($/;"	p
+psDeproject	src/astronomy/psCoord.c	/^psSphere* psDeproject(const psPlane* coord,$/;"	f
+psDeproject	src/astronomy/psCoord.h	/^psSphere* psDeproject($/;"	p
+psDimen	include/psType.h	/^} psDimen;$/;"	t
+psDimen	src/sysUtils/psType.h	/^} psDimen;$/;"	t
+psElemType	include/psType.h	/^} psElemType;$/;"	t
+psElemType	src/sysUtils/psType.h	/^} psElemType;$/;"	t
+psErr	include/psError.h	/^psErr;$/;"	t
+psErr	src/sysUtils/psError.h	/^psErr;$/;"	t
+psErrAlloc	include/psError.h	/^psErr* psErrAlloc($/;"	p
+psErrAlloc	src/sysUtils/psError.c	/^psErr* psErrAlloc(const char* name, psErrorCode code, const char* msg)$/;"	f
+psErrAlloc	src/sysUtils/psError.h	/^psErr* psErrAlloc($/;"	p
+psError	include/psError.h	/^#define psError(/;"	d
+psError	src/sysUtils/psError.h	/^#define psError(/;"	d
+psErrorClear	include/psError.h	/^void psErrorClear(void);$/;"	p
+psErrorClear	src/sysUtils/psError.c	/^void psErrorClear(void)$/;"	f
+psErrorClear	src/sysUtils/psError.h	/^void psErrorClear(void);$/;"	p
+psErrorCode	include/psErrorCodes.h	/^} psErrorCode;$/;"	t
+psErrorCode	src/sysUtils/psErrorCodes.h	/^} psErrorCode;$/;"	t
+psErrorCodeString	include/psErrorCodes.h	/^const char *psErrorCodeString($/;"	p
+psErrorCodeString	src/sysUtils/psErrorCodes.c	/^const char *psErrorCodeString(psErrorCode code)$/;"	f
+psErrorCodeString	src/sysUtils/psErrorCodes.h	/^const char *psErrorCodeString($/;"	p
+psErrorDescription	include/psErrorCodes.h	/^psErrorDescription;$/;"	t
+psErrorDescription	src/sysUtils/psErrorCodes.h	/^psErrorDescription;$/;"	t
+psErrorDescriptionAlloc	include/psErrorCodes.h	/^psErrorDescription* psErrorDescriptionAlloc($/;"	p
+psErrorDescriptionAlloc	src/sysUtils/psErrorCodes.c	/^psErrorDescription* psErrorDescriptionAlloc(psErrorCode code,$/;"	f
+psErrorDescriptionAlloc	src/sysUtils/psErrorCodes.h	/^psErrorDescription* psErrorDescriptionAlloc($/;"	p
+psErrorGet	include/psError.h	/^psErr* psErrorGet($/;"	p
+psErrorGet	src/sysUtils/psError.c	/^psErr* psErrorGet(psS32 which)$/;"	f
+psErrorGet	src/sysUtils/psError.h	/^psErr* psErrorGet($/;"	p
+psErrorLast	include/psError.h	/^psErr* psErrorLast(void);$/;"	p
+psErrorLast	src/sysUtils/psError.c	/^psErr* psErrorLast(void)$/;"	f
+psErrorLast	src/sysUtils/psError.h	/^psErr* psErrorLast(void);$/;"	p
+psErrorRegister	include/psErrorCodes.h	/^void psErrorRegister($/;"	p
+psErrorRegister	src/sysUtils/psErrorCodes.c	/^void psErrorRegister(const psErrorDescription* errors,$/;"	f
+psErrorRegister	src/sysUtils/psErrorCodes.h	/^void psErrorRegister($/;"	p
+psErrorStackPrint	include/psError.h	/^void psErrorStackPrint($/;"	p
+psErrorStackPrint	src/sysUtils/psError.c	/^void psErrorStackPrint(FILE *fd, const char *fmt, ...)$/;"	f
+psErrorStackPrint	src/sysUtils/psError.h	/^void psErrorStackPrint($/;"	p
+psErrorStackPrintV	include/psError.h	/^void psErrorStackPrintV($/;"	p
+psErrorStackPrintV	src/sysUtils/psError.c	/^void psErrorStackPrintV(FILE *fd, const char *fmt, va_list va)$/;"	f
+psErrorStackPrintV	src/sysUtils/psError.h	/^void psErrorStackPrintV($/;"	p
+psExposure	include/psAstrometry.h	/^psExposure;$/;"	t
+psExposure	include/psAstrometry.h	/^typedef struct psExposure$/;"	s
+psExposure	src/astronomy/psAstrometry.h	/^psExposure;$/;"	t
+psExposure	src/astronomy/psAstrometry.h	/^typedef struct psExposure$/;"	s
+psExposureAlloc	include/psAstrometry.h	/^psExposure* psExposureAlloc($/;"	p
+psExposureAlloc	src/astronomy/psAstrometry.c	/^psExposure* psExposureAlloc(double ra,$/;"	f
+psExposureAlloc	src/astronomy/psAstrometry.h	/^psExposure* psExposureAlloc($/;"	p
+psF32	include/psType.h	/^typedef float psF32;                   \/\/\/< 32-bit floating point$/;"	t
+psF32	src/sysUtils/psType.h	/^typedef float psF32;                   \/\/\/< 32-bit floating point$/;"	t
+psF64	include/psType.h	/^typedef double psF64;                  \/\/\/< 64-bit floating point$/;"	t
+psF64	src/sysUtils/psType.h	/^typedef double psF64;                  \/\/\/< 64-bit floating point$/;"	t
+psFFTFlags	include/psVectorFFT.h	/^} psFFTFlags;$/;"	t
+psFFTFlags	src/dataManip/psVectorFFT.h	/^} psFFTFlags;$/;"	t
+psFPA	include/psAstrometry.h	/^psFPA;$/;"	t
+psFPA	include/psAstrometry.h	/^typedef struct psFPA$/;"	s
+psFPA	src/astronomy/psAstrometry.h	/^psFPA;$/;"	t
+psFPA	src/astronomy/psAstrometry.h	/^typedef struct psFPA$/;"	s
+psFPAAlloc	include/psAstrometry.h	/^psFPA* psFPAAlloc($/;"	p
+psFPAAlloc	src/astronomy/psAstrometry.c	/^psFPA* psFPAAlloc(psS32 nChips,$/;"	f
+psFPAAlloc	src/astronomy/psAstrometry.h	/^psFPA* psFPAAlloc($/;"	p
+psFits	src/fileUtils/psFits.h	/^psFits;$/;"	t
+psFitsAlloc	src/fileUtils/psFits.c	/^psFits* psFitsAlloc(const char* name,                  \/\/\/< the FITS file name$/;"	f
+psFitsAlloc	src/fileUtils/psFits.h	/^psFits* psFitsAlloc($/;"	p
+psFitsGetExtName	src/fileUtils/psFits.c	/^char* psFitsGetExtName(psFits* fits)$/;"	f
+psFitsGetExtName	src/fileUtils/psFits.h	/^char* psFitsGetExtName($/;"	p
+psFitsGetExtNum	src/fileUtils/psFits.c	/^int psFitsGetExtNum(psFits* fits)$/;"	f
+psFitsGetExtNum	src/fileUtils/psFits.h	/^int psFitsGetExtNum($/;"	p
+psFitsGetExtType	src/fileUtils/psFits.c	/^psFitsType psFitsGetExtType(psFits* fits)$/;"	f
+psFitsGetExtType	src/fileUtils/psFits.h	/^psFitsType psFitsGetExtType($/;"	p
+psFitsGetSize	src/fileUtils/psFits.c	/^int psFitsGetSize(psFits* fits)$/;"	f
+psFitsGetSize	src/fileUtils/psFits.h	/^int psFitsGetSize($/;"	p
+psFitsMoveExtName	src/fileUtils/psFits.c	/^bool psFitsMoveExtName(psFits* fits,$/;"	f
+psFitsMoveExtName	src/fileUtils/psFits.h	/^bool psFitsMoveExtName($/;"	p
+psFitsMoveExtNum	src/fileUtils/psFits.c	/^bool psFitsMoveExtNum(psFits* fits,$/;"	f
+psFitsMoveExtNum	src/fileUtils/psFits.h	/^bool psFitsMoveExtNum($/;"	p
+psFitsReadHeader	src/fileUtils/psFits.c	/^psMetadata* psFitsReadHeader(psMetadata* out,$/;"	f
+psFitsReadHeader	src/fileUtils/psFits.h	/^psMetadata* psFitsReadHeader($/;"	p
+psFitsReadHeaderSet	src/fileUtils/psFits.c	/^psHash* psFitsReadHeaderSet(psHash* out,$/;"	f
+psFitsReadHeaderSet	src/fileUtils/psFits.h	/^psHash* psFitsReadHeaderSet($/;"	p
+psFitsReadImageSection	src/fileUtils/psFits.h	/^psImage* psFitsReadImageSection($/;"	p
+psFitsReadTable	src/fileUtils/psFits.c	/^psArray* psFitsReadTable(psFits* fits)$/;"	f
+psFitsReadTable	src/fileUtils/psFits.h	/^psArray* psFitsReadTable($/;"	p
+psFitsReadTableColumn	src/fileUtils/psFits.c	/^psArray* psFitsReadTableColumn(psFits* fits,$/;"	f
+psFitsReadTableColumn	src/fileUtils/psFits.h	/^psArray* psFitsReadTableColumn($/;"	p
+psFitsReadTableColumnNum	src/fileUtils/psFits.c	/^psVector* psFitsReadTableColumnNum(psFits* fits,$/;"	f
+psFitsReadTableColumnNum	src/fileUtils/psFits.h	/^psVector* psFitsReadTableColumnNum($/;"	p
+psFitsReadTableRow	src/fileUtils/psFits.c	/^psMetadata* psFitsReadTableRow(psFits* fits,$/;"	f
+psFitsReadTableRow	src/fileUtils/psFits.h	/^psMetadata* psFitsReadTableRow($/;"	p
+psFitsType	src/fileUtils/psFits.h	/^} psFitsType;$/;"	t
+psFitsWriteHeader	src/fileUtils/psFits.c	/^bool psFitsWriteHeader(const psMetadata* header,$/;"	f
+psFitsWriteHeader	src/fileUtils/psFits.h	/^bool psFitsWriteHeader($/;"	p
+psFitsWriteImage	src/fileUtils/psFits.c	/^bool psFitsWriteImage(psFits* fits,$/;"	f
+psFitsWriteImage	src/fileUtils/psFits.h	/^bool psFitsWriteImage($/;"	p
+psFitsWriteTable	src/fileUtils/psFits.c	/^bool psFitsWriteTable(psFits* fits,$/;"	f
+psFitsWriteTable	src/fileUtils/psFits.h	/^bool psFitsWriteTable($/;"	p
+psFixedPattern	include/psAstrometry.h	/^psFixedPattern;$/;"	t
+psFixedPattern	src/astronomy/psAstrometry.h	/^psFixedPattern;$/;"	t
+psFixedPatternAlloc	include/psAstrometry.h	/^psFixedPattern* psFixedPatternAlloc($/;"	p
+psFixedPatternAlloc	src/astronomy/psAstrometry.c	/^psFixedPattern* psFixedPatternAlloc(double x0,$/;"	f
+psFixedPatternAlloc	src/astronomy/psAstrometry.h	/^psFixedPattern* psFixedPatternAlloc($/;"	p
+psFree	include/psMemory.h	/^#define psFree(/;"	d
+psFree	include/psMemory.h	/^void psFree($/;"	p
+psFree	src/sysUtils/psMemory.h	/^#define psFree(/;"	d
+psFree	src/sysUtils/psMemory.h	/^void psFree($/;"	p
+psFreeFcn	include/psMemory.h	/^typedef void (*psFreeFcn) (psPtr ptr);$/;"	t
+psFreeFcn	src/sysUtils/psMemory.h	/^typedef void (*psFreeFcn) (psPtr ptr);$/;"	t
+psGaussian	include/psFunctions.h	/^psF32 psGaussian($/;"	p
+psGaussian	src/dataManip/psFunctions.c	/^psF32 psGaussian(psF32 x, psF32 mean, psF32 sigma, psBool normal)$/;"	f
+psGaussian	src/dataManip/psFunctions.h	/^psF32 psGaussian($/;"	p
+psGrommit	include/psAstrometry.h	/^psGrommit;$/;"	t
+psGrommit	src/astronomy/psAstrometry.h	/^psGrommit;$/;"	t
+psGrommitAlloc	include/psAstrometry.h	/^psGrommit* psGrommitAlloc($/;"	p
+psGrommitAlloc	src/astronomy/psAstrometry.c	/^psGrommit* psGrommitAlloc(const psExposure* exp)$/;"	f
+psGrommitAlloc	src/astronomy/psAstrometry.h	/^psGrommit* psGrommitAlloc($/;"	p
+psHash	include/psHash.h	/^psHash;$/;"	t
+psHash	include/psHash.h	/^typedef struct psHash$/;"	s
+psHash	src/collections/psHash.h	/^psHash;$/;"	t
+psHash	src/collections/psHash.h	/^typedef struct psHash$/;"	s
+psHashAdd	include/psHash.h	/^psBool psHashAdd(psHash* table,  \/\/\/< table to insert in$/;"	p
+psHashAdd	src/collections/psHash.c	/^psBool psHashAdd(psHash* table,$/;"	f
+psHashAdd	src/collections/psHash.h	/^psBool psHashAdd(psHash* table,  \/\/\/< table to insert in$/;"	p
+psHashAlloc	include/psHash.h	/^psHash* psHashAlloc(psS32 nbucket \/\/\/< The number of buckets to allocate.$/;"	p
+psHashAlloc	src/collections/psHash.c	/^psHash* psHashAlloc(psS32 nbucket)        \/\/ initial number of buckets$/;"	f
+psHashAlloc	src/collections/psHash.h	/^psHash* psHashAlloc(psS32 nbucket \/\/\/< The number of buckets to allocate.$/;"	p
+psHashBucket	include/psHash.h	/^psHashBucket;$/;"	t
+psHashBucket	include/psHash.h	/^typedef struct psHashBucket$/;"	s
+psHashBucket	src/collections/psHash.h	/^psHashBucket;$/;"	t
+psHashBucket	src/collections/psHash.h	/^typedef struct psHashBucket$/;"	s
+psHashKeyList	include/psHash.h	/^psList* psHashKeyList(psHash* table    \/\/\/< table to list keys from.$/;"	p
+psHashKeyList	src/collections/psHash.c	/^psList* psHashKeyList(psHash* table)$/;"	f
+psHashKeyList	src/collections/psHash.h	/^psList* psHashKeyList(psHash* table    \/\/\/< table to list keys from.$/;"	p
+psHashLookup	include/psHash.h	/^psPtr psHashLookup(psHash* table,      \/\/\/< table to lookup key in$/;"	p
+psHashLookup	src/collections/psHash.c	/^psPtr psHashLookup(psHash* table,      \/\/ table to lookup key in$/;"	f
+psHashLookup	src/collections/psHash.h	/^psPtr psHashLookup(psHash* table,      \/\/\/< table to lookup key in$/;"	p
+psHashRemove	include/psHash.h	/^psBool psHashRemove(psHash* table,       \/\/\/< table to lookup key in$/;"	p
+psHashRemove	src/collections/psHash.c	/^psBool psHashRemove(psHash* table,$/;"	f
+psHashRemove	src/collections/psHash.h	/^psBool psHashRemove(psHash* table,       \/\/\/< table to lookup key in$/;"	p
+psHistogram	include/psStats.h	/^psHistogram;$/;"	t
+psHistogram	src/dataManip/psStats.h	/^psHistogram;$/;"	t
+psHistogramAlloc	include/psStats.h	/^psHistogram* psHistogramAlloc($/;"	p
+psHistogramAlloc	src/dataManip/psStats.c	/^psHistogram* psHistogramAlloc(psF32 lower, psF32 upper, psS32 n)$/;"	f
+psHistogramAlloc	src/dataManip/psStats.h	/^psHistogram* psHistogramAlloc($/;"	p
+psHistogramAllocGeneric	include/psStats.h	/^psHistogram* psHistogramAllocGeneric($/;"	p
+psHistogramAllocGeneric	src/dataManip/psStats.c	/^psHistogram* psHistogramAllocGeneric(const psVector* restrict bounds)$/;"	f
+psHistogramAllocGeneric	src/dataManip/psStats.h	/^psHistogram* psHistogramAllocGeneric($/;"	p
+psImage	include/psImage.h	/^psImage;$/;"	t
+psImage	include/psImage.h	/^typedef struct psImage$/;"	s
+psImage	src/image/psImage.h	/^psImage;$/;"	t
+psImage	src/image/psImage.h	/^typedef struct psImage$/;"	s
+psImageAlloc	include/psImage.h	/^psImage* psImageAlloc($/;"	p
+psImageAlloc	src/image/psImage.c	/^psImage* psImageAlloc(psU32 numCols,$/;"	f
+psImageAlloc	src/image/psImage.h	/^psImage* psImageAlloc($/;"	p
+psImageClip	include/psImageManip.h	/^psS32 psImageClip($/;"	p
+psImageClip	src/image/psImageManip.c	/^psS32 psImageClip(psImage* input,$/;"	f
+psImageClip	src/image/psImageManip.h	/^psS32 psImageClip($/;"	p
+psImageClipCase	src/image/psImageManip.c	/^        #define psImageClipCase(/;"	d	file:
+psImageClipCaseComplex	src/image/psImageManip.c	/^        #define psImageClipCaseComplex(/;"	d	file:
+psImageClipComplexRegion	include/psImageManip.h	/^psS32 psImageClipComplexRegion($/;"	p
+psImageClipComplexRegion	src/image/psImageManip.c	/^psS32 psImageClipComplexRegion(psImage* input,$/;"	f
+psImageClipComplexRegion	src/image/psImageManip.h	/^psS32 psImageClipComplexRegion($/;"	p
+psImageClipComplexRegionCase	src/image/psImageManip.c	/^    #define psImageClipComplexRegionCase(/;"	d	file:
+psImageClipNaN	include/psImageManip.h	/^psS32 psImageClipNaN($/;"	p
+psImageClipNaN	src/image/psImageManip.c	/^psS32 psImageClipNaN(psImage* input,$/;"	f
+psImageClipNaN	src/image/psImageManip.h	/^psS32 psImageClipNaN($/;"	p
+psImageClipNaNCase	src/image/psImageManip.c	/^        #define psImageClipNaNCase(/;"	d	file:
+psImageComplex	include/psImageFFT.h	/^psImage* psImageComplex($/;"	p
+psImageComplex	src/image/psImageFFT.c	/^psImage* psImageComplex(psImage* out, const psImage* real, const psImage* imag)$/;"	f
+psImageComplex	src/image/psImageFFT.h	/^psImage* psImageComplex($/;"	p
+psImageConjugate	include/psImageFFT.h	/^psImage* psImageConjugate($/;"	p
+psImageConjugate	src/image/psImageFFT.c	/^psImage* psImageConjugate(psImage* out, const psImage* in)$/;"	f
+psImageConjugate	src/image/psImageFFT.h	/^psImage* psImageConjugate($/;"	p
+psImageConvolve	include/psImageConvolve.h	/^psImage* psImageConvolve($/;"	p
+psImageConvolve	src/image/psImageConvolve.c	/^psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, psBool direct)$/;"	f
+psImageConvolve	src/image/psImageConvolve.h	/^psImage* psImageConvolve($/;"	p
+psImageCopy	include/psImage.h	/^psImage* psImageCopy($/;"	p
+psImageCopy	src/image/psImage.c	/^psImage* psImageCopy(psImage* restrict output,$/;"	f
+psImageCopy	src/image/psImage.h	/^psImage* psImageCopy($/;"	p
+psImageCut	include/psImageExtraction.h	/^psVector* psImageCut($/;"	p
+psImageCut	src/image/psImageExtraction.c	/^psVector* psImageCut(psVector* out,$/;"	f
+psImageCut	src/image/psImageExtraction.h	/^psVector* psImageCut($/;"	p
+psImageCutDirection	include/psImageExtraction.h	/^} psImageCutDirection;$/;"	t
+psImageCutDirection	src/image/psImageExtraction.h	/^} psImageCutDirection;$/;"	t
+psImageEvalPolynomial	include/psImageStats.h	/^psImage* psImageEvalPolynomial($/;"	p
+psImageEvalPolynomial	src/image/psImageStats.c	/^psImage* psImageEvalPolynomial(psImage* input,$/;"	f
+psImageEvalPolynomial	src/image/psImageStats.h	/^psImage* psImageEvalPolynomial($/;"	p
+psImageFFT	include/psImageFFT.h	/^psImage* psImageFFT($/;"	p
+psImageFFT	src/image/psImageFFT.c	/^psImage* psImageFFT(psImage* out, const psImage* in, psFFTFlags direction)$/;"	f
+psImageFFT	src/image/psImageFFT.h	/^psImage* psImageFFT($/;"	p
+psImageFitPolynomial	include/psImageStats.h	/^psPolynomial2D* psImageFitPolynomial($/;"	p
+psImageFitPolynomial	src/image/psImageStats.c	/^psPolynomial2D* psImageFitPolynomial(psPolynomial2D* coeffs,$/;"	f
+psImageFitPolynomial	src/image/psImageStats.h	/^psPolynomial2D* psImageFitPolynomial($/;"	p
+psImageFitPolynomialTest	src/image/psImageStats.c	/^psPolynomial2D* psImageFitPolynomialTest(psPolynomial2D* coeffs,$/;"	f
+psImageFreeChildren	include/psImage.h	/^psS32 psImageFreeChildren($/;"	p
+psImageFreeChildren	src/image/psImage.c	/^psS32 psImageFreeChildren(psImage* image)$/;"	f
+psImageFreeChildren	src/image/psImage.h	/^psS32 psImageFreeChildren($/;"	p
+psImageHistogram	include/psImageStats.h	/^psHistogram* psImageHistogram($/;"	p
+psImageHistogram	src/image/psImageStats.c	/^psHistogram* psImageHistogram(psHistogram* out,$/;"	f
+psImageHistogram	src/image/psImageStats.h	/^psHistogram* psImageHistogram($/;"	p
+psImageImaginary	include/psImageFFT.h	/^psImage* psImageImaginary($/;"	p
+psImageImaginary	src/image/psImageFFT.c	/^psImage* psImageImaginary(psImage* out, const psImage* in)$/;"	f
+psImageImaginary	src/image/psImageFFT.h	/^psImage* psImageImaginary($/;"	p
+psImageInterpolateMode	include/psImage.h	/^} psImageInterpolateMode;$/;"	t
+psImageInterpolateMode	src/image/psImage.h	/^} psImageInterpolateMode;$/;"	t
+psImageOverlayCase	src/image/psImageManip.c	/^        #define psImageOverlayCase(/;"	d	file:
+psImageOverlaySection	include/psImageManip.h	/^psS32 psImageOverlaySection($/;"	p
+psImageOverlaySection	src/image/psImageManip.c	/^psS32 psImageOverlaySection(psImage* image,$/;"	f
+psImageOverlaySection	src/image/psImageManip.h	/^psS32 psImageOverlaySection($/;"	p
+psImagePixelInterpolate	include/psImage.h	/^psC64 psImagePixelInterpolate($/;"	p
+psImagePixelInterpolate	src/image/psImage.c	/^psC64 psImagePixelInterpolate(const psImage* input,$/;"	f
+psImagePixelInterpolate	src/image/psImage.h	/^psC64 psImagePixelInterpolate($/;"	p
+psImagePowerSpectrum	include/psImageFFT.h	/^psImage* psImagePowerSpectrum($/;"	p
+psImagePowerSpectrum	src/image/psImageFFT.c	/^psImage* psImagePowerSpectrum(psImage* out, const psImage* in)$/;"	f
+psImagePowerSpectrum	src/image/psImageFFT.h	/^psImage* psImagePowerSpectrum($/;"	p
+psImageRadialCut	include/psImageExtraction.h	/^psVector* psImageRadialCut($/;"	p
+psImageRadialCut	src/image/psImageExtraction.c	/^psVector* psImageRadialCut(psVector* out,$/;"	f
+psImageRadialCut	src/image/psImageExtraction.h	/^psVector* psImageRadialCut($/;"	p
+psImageReadSection	include/psImageIO.h	/^psImage* psImageReadSection($/;"	p
+psImageReadSection	src/image/psImageIO.c	/^psImage* psImageReadSection(psImage* output,$/;"	f
+psImageReadSection	src/image/psImageIO.h	/^psImage* psImageReadSection($/;"	p
+psImageReal	include/psImageFFT.h	/^psImage* psImageReal($/;"	p
+psImageReal	src/image/psImageFFT.c	/^psImage* psImageReal(psImage* out, const psImage* in)$/;"	f
+psImageReal	src/image/psImageFFT.h	/^psImage* psImageReal($/;"	p
+psImageRebin	include/psImageManip.h	/^psImage* psImageRebin($/;"	p
+psImageRebin	src/image/psImageManip.c	/^psImage* psImageRebin(psImage* out,$/;"	f
+psImageRebin	src/image/psImageManip.h	/^psImage* psImageRebin($/;"	p
+psImageRecycle	include/psImage.h	/^psImage* psImageRecycle($/;"	p
+psImageRecycle	src/image/psImage.c	/^psImage* psImageRecycle(psImage* old,$/;"	f
+psImageRecycle	src/image/psImage.h	/^psImage* psImageRecycle($/;"	p
+psImageResample	include/psImageManip.h	/^psImage* psImageResample($/;"	p
+psImageResample	src/image/psImageManip.c	/^psImage* psImageResample(psImage* out,$/;"	f
+psImageResample	src/image/psImageManip.h	/^psImage* psImageResample($/;"	p
+psImageRoll	include/psImageManip.h	/^psImage* psImageRoll($/;"	p
+psImageRoll	src/image/psImageManip.c	/^psImage* psImageRoll(psImage* out,$/;"	f
+psImageRoll	src/image/psImageManip.h	/^psImage* psImageRoll($/;"	p
+psImageRotate	include/psImageManip.h	/^psImage* psImageRotate($/;"	p
+psImageRotate	src/image/psImageManip.c	/^psImage* psImageRotate(psImage* out,$/;"	f
+psImageRotate	src/image/psImageManip.h	/^psImage* psImageRotate($/;"	p
+psImageShift	include/psImageManip.h	/^psImage* psImageShift($/;"	p
+psImageShift	src/image/psImageManip.c	/^psImage* psImageShift(psImage* out,$/;"	f
+psImageShift	src/image/psImageManip.h	/^psImage* psImageShift($/;"	p
+psImageSlice	include/psImageExtraction.h	/^psVector* psImageSlice($/;"	p
+psImageSlice	src/image/psImageExtraction.c	/^psVector* psImageSlice(psVector* out,$/;"	f
+psImageSlice	src/image/psImageExtraction.h	/^psVector* psImageSlice($/;"	p
+psImageStats	include/psImageStats.h	/^psStats* psImageStats($/;"	p
+psImageStats	src/image/psImageStats.c	/^psStats* psImageStats(psStats* stats,$/;"	f
+psImageStats	src/image/psImageStats.h	/^psStats* psImageStats($/;"	p
+psImageSubsection	include/psImageExtraction.h	/^psImage* psImageSubsection($/;"	p
+psImageSubsection	src/image/psImageExtraction.c	/^psImage* psImageSubsection(psImage* image,$/;"	f
+psImageSubsection	src/image/psImageExtraction.h	/^psImage* psImageSubsection($/;"	p
+psImageSubset	include/psImageExtraction.h	/^psImage* psImageSubset($/;"	p
+psImageSubset	src/image/psImageExtraction.c	/^psImage* psImageSubset(psImage* image,$/;"	f
+psImageSubset	src/image/psImageExtraction.h	/^psImage* psImageSubset($/;"	p
+psImageToGslMatrix	src/dataManip/psMatrix.c	/^static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage)$/;"	f	file:
+psImageToGslMatrix	src/dataManip/psMatrix.c	/^static void  psImageToGslMatrix(gsl_matrix *outGslMatrix, const psImage *inImage);$/;"	p	file:
+psImageTrim	include/psImageExtraction.h	/^psImage* psImageTrim($/;"	p
+psImageTrim	src/image/psImageExtraction.c	/^psImage* psImageTrim(psImage* image, psS32 col0, psS32 row0, psS32 col1, psS32 row1)$/;"	f
+psImageTrim	src/image/psImageExtraction.h	/^psImage* psImageTrim($/;"	p
+psImageWriteSection	include/psImageIO.h	/^psBool psImageWriteSection($/;"	p
+psImageWriteSection	src/image/psImageIO.c	/^psBool psImageWriteSection(psImage* input,$/;"	f
+psImageWriteSection	src/image/psImageIO.h	/^psBool psImageWriteSection($/;"	p
+psKernel	include/psImageConvolve.h	/^psKernel;$/;"	t
+psKernel	src/image/psImageConvolve.h	/^psKernel;$/;"	t
+psKernelAlloc	include/psImageConvolve.h	/^psKernel* psKernelAlloc($/;"	p
+psKernelAlloc	src/image/psImageConvolve.c	/^psKernel* psKernelAlloc(psS32 xMin, psS32 xMax, psS32 yMin, psS32 yMax)$/;"	f
+psKernelAlloc	src/image/psImageConvolve.h	/^psKernel* psKernelAlloc($/;"	p
+psKernelGenerate	include/psImageConvolve.h	/^psKernel* psKernelGenerate($/;"	p
+psKernelGenerate	src/image/psImageConvolve.c	/^psKernel* psKernelGenerate(const psVector* tShifts,$/;"	f
+psKernelGenerate	src/image/psImageConvolve.h	/^psKernel* psKernelGenerate($/;"	p
+psKernelType	include/psImageConvolve.h	/^typedef psF32 psKernelType;$/;"	t
+psKernelType	src/image/psImageConvolve.h	/^typedef psF32 psKernelType;$/;"	t
+psLibFinalize	include/psConfigure.h	/^void psLibFinalize($/;"	p
+psLibFinalize	src/sysUtils/psConfigure.c	/^void psLibFinalize(void)$/;"	f
+psLibFinalize	src/sysUtils/psConfigure.h	/^void psLibFinalize($/;"	p
+psLibInit	include/psConfigure.h	/^void psLibInit($/;"	p
+psLibInit	src/sysUtils/psConfigure.c	/^void psLibInit(bool predictable, const char* timeConfig)$/;"	f
+psLibInit	src/sysUtils/psConfigure.h	/^void psLibInit($/;"	p
+psLibVersion	include/psConfigure.h	/^char* psLibVersion($/;"	p
+psLibVersion	src/sysUtils/psConfigure.c	/^char* psLibVersion(void)$/;"	f
+psLibVersion	src/sysUtils/psConfigure.h	/^char* psLibVersion($/;"	p
+psList	include/psList.h	/^psList;$/;"	t
+psList	src/collections/psList.h	/^psList;$/;"	t
+psListAdd	include/psList.h	/^psBool psListAdd($/;"	p
+psListAdd	src/collections/psList.c	/^psBool psListAdd(psList* list, psS32 location, psPtr data)$/;"	f
+psListAdd	src/collections/psList.h	/^psBool psListAdd($/;"	p
+psListAddAfter	include/psList.h	/^psBool psListAddAfter($/;"	p
+psListAddAfter	src/collections/psList.c	/^bool psListAddAfter(psListIterator* iterator, void* data)$/;"	f
+psListAddAfter	src/collections/psList.h	/^psBool psListAddAfter($/;"	p
+psListAddBefore	include/psList.h	/^psBool psListAddBefore($/;"	p
+psListAddBefore	src/collections/psList.c	/^bool psListAddBefore(psListIterator* iterator, void* data)$/;"	f
+psListAddBefore	src/collections/psList.h	/^psBool psListAddBefore($/;"	p
+psListAlloc	include/psList.h	/^psList* psListAlloc($/;"	p
+psListAlloc	src/collections/psList.c	/^psList* psListAlloc(psPtr data)$/;"	f
+psListAlloc	src/collections/psList.h	/^psList* psListAlloc($/;"	p
+psListElem	include/psList.h	/^psListElem;$/;"	t
+psListElem	include/psList.h	/^typedef struct psListElem$/;"	s
+psListElem	src/collections/psList.h	/^psListElem;$/;"	t
+psListElem	src/collections/psList.h	/^typedef struct psListElem$/;"	s
+psListGet	include/psList.h	/^psPtr psListGet($/;"	p
+psListGet	src/collections/psList.c	/^psPtr psListGet(psList* list, psS32 location)$/;"	f
+psListGet	src/collections/psList.h	/^psPtr psListGet($/;"	p
+psListGetNext	include/psList.h	/^psPtr psListGetNext($/;"	p
+psListGetNext	src/collections/psList.c	/^psPtr psListGetNext(psListIterator* iterator)$/;"	f
+psListGetNext	src/collections/psList.h	/^psPtr psListGetNext($/;"	p
+psListGetPrevious	include/psList.h	/^psPtr psListGetPrevious($/;"	p
+psListGetPrevious	src/collections/psList.c	/^psPtr psListGetPrevious(psListIterator* iterator)$/;"	f
+psListGetPrevious	src/collections/psList.h	/^psPtr psListGetPrevious($/;"	p
+psListIterator	include/psList.h	/^psListIterator;$/;"	t
+psListIterator	src/collections/psList.h	/^psListIterator;$/;"	t
+psListIteratorAlloc	include/psList.h	/^psListIterator* psListIteratorAlloc($/;"	p
+psListIteratorAlloc	src/collections/psList.c	/^psListIterator* psListIteratorAlloc(psList* list, int location)$/;"	f
+psListIteratorAlloc	src/collections/psList.h	/^psListIterator* psListIteratorAlloc($/;"	p
+psListIteratorSet	include/psList.h	/^psBool psListIteratorSet($/;"	p
+psListIteratorSet	src/collections/psList.c	/^psBool psListIteratorSet(psListIterator* iterator,$/;"	f
+psListIteratorSet	src/collections/psList.h	/^psBool psListIteratorSet($/;"	p
+psListRemove	include/psList.h	/^psBool psListRemove($/;"	p
+psListRemove	src/collections/psList.c	/^psBool psListRemove(psList* list,$/;"	f
+psListRemove	src/collections/psList.h	/^psBool psListRemove($/;"	p
+psListRemoveData	include/psList.h	/^psBool psListRemoveData($/;"	p
+psListRemoveData	src/collections/psList.c	/^psBool psListRemoveData(psList* list,$/;"	f
+psListRemoveData	src/collections/psList.h	/^psBool psListRemoveData($/;"	p
+psListSort	include/psList.h	/^psList* psListSort($/;"	p
+psListSort	src/collections/psList.c	/^psList* psListSort(psList* list, psComparePtrFcn compare)$/;"	f
+psListSort	src/collections/psList.h	/^psList* psListSort($/;"	p
+psListToArray	include/psList.h	/^psArray* psListToArray($/;"	p
+psListToArray	src/collections/psList.c	/^psArray* psListToArray(psList* restrict list)$/;"	f
+psListToArray	src/collections/psList.h	/^psArray* psListToArray($/;"	p
+psLogMsg	include/psLogMsg.h	/^void psLogMsg($/;"	p
+psLogMsg	src/sysUtils/psLogMsg.c	/^void psLogMsg(const char *name, psS32 level, const char *fmt, ...)$/;"	f
+psLogMsg	src/sysUtils/psLogMsg.h	/^void psLogMsg($/;"	p
+psLogMsgV	include/psLogMsg.h	/^void psLogMsgV($/;"	p
+psLogMsgV	src/sysUtils/psLogMsg.c	/^void psLogMsgV(const char *name, psS32 level, const char *fmt, va_list ap)$/;"	f
+psLogMsgV	src/sysUtils/psLogMsg.h	/^void psLogMsgV($/;"	p
+psLogSetDestination	include/psLogMsg.h	/^psBool psLogSetDestination($/;"	p
+psLogSetDestination	src/sysUtils/psLogMsg.c	/^psBool psLogSetDestination(const char *dest)$/;"	f
+psLogSetDestination	src/sysUtils/psLogMsg.h	/^psBool psLogSetDestination($/;"	p
+psLogSetFormat	include/psLogMsg.h	/^void psLogSetFormat($/;"	p
+psLogSetFormat	src/sysUtils/psLogMsg.c	/^void psLogSetFormat(const char *fmt)$/;"	f
+psLogSetFormat	src/sysUtils/psLogMsg.h	/^void psLogSetFormat($/;"	p
+psLogSetLevel	include/psLogMsg.h	/^psS32 psLogSetLevel($/;"	p
+psLogSetLevel	src/sysUtils/psLogMsg.c	/^psS32 psLogSetLevel(psS32 level)$/;"	f
+psLogSetLevel	src/sysUtils/psLogMsg.h	/^psS32 psLogSetLevel($/;"	p
+psLookupStatusType	include/psLookupTable.h	/^} psLookupStatusType;$/;"	t
+psLookupStatusType	src/fileUtils/psLookupTable.h	/^} psLookupStatusType;$/;"	t
+psLookupTable	include/psLookupTable.h	/^psLookupTable;$/;"	t
+psLookupTable	src/fileUtils/psLookupTable.h	/^psLookupTable;$/;"	t
+psLookupTableAlloc	include/psLookupTable.h	/^psLookupTable* psLookupTableAlloc($/;"	p
+psLookupTableAlloc	src/fileUtils/psLookupTable.c	/^psLookupTable* psLookupTableAlloc(const char *fileName, psF64 validFrom, psF64 validTo)$/;"	f
+psLookupTableAlloc	src/fileUtils/psLookupTable.h	/^psLookupTable* psLookupTableAlloc($/;"	p
+psLookupTableInterpolate	include/psLookupTable.h	/^psF64 psLookupTableInterpolate($/;"	p
+psLookupTableInterpolate	src/fileUtils/psLookupTable.c	/^psF64 psLookupTableInterpolate(psLookupTable *table, psF64 index, psU64 column, psLookupStatusType *status)$/;"	f
+psLookupTableInterpolate	src/fileUtils/psLookupTable.h	/^psF64 psLookupTableInterpolate($/;"	p
+psLookupTableInterpolateAll	include/psLookupTable.h	/^psVector* psLookupTableInterpolateAll($/;"	p
+psLookupTableInterpolateAll	src/fileUtils/psLookupTable.c	/^psVector* psLookupTableInterpolateAll(psLookupTable *table, psF64 index, psVector *stats)$/;"	f
+psLookupTableInterpolateAll	src/fileUtils/psLookupTable.h	/^psVector* psLookupTableInterpolateAll($/;"	p
+psLookupTableRead	include/psLookupTable.h	/^psLookupTable* psLookupTableRead($/;"	p
+psLookupTableRead	src/fileUtils/psLookupTable.c	/^psLookupTable* psLookupTableRead(psLookupTable *table)$/;"	f
+psLookupTableRead	src/fileUtils/psLookupTable.h	/^psLookupTable* psLookupTableRead($/;"	p
+psMaskType	include/psType.h	/^typedef psU8 psMaskType;               \/\/\/< the C datatype for a mask image$/;"	t
+psMaskType	src/sysUtils/psType.h	/^typedef psU8 psMaskType;               \/\/\/< the C datatype for a mask image$/;"	t
+psMath	include/psType.h	/^psMath;$/;"	t
+psMath	src/sysUtils/psType.h	/^psMath;$/;"	t
+psMatrixDeterminant	include/psMatrix.h	/^psF32 *psMatrixDeterminant($/;"	p
+psMatrixDeterminant	src/dataManip/psMatrix.c	/^psF32 *psMatrixDeterminant(const psImage* inImage)$/;"	f
+psMatrixDeterminant	src/dataManip/psMatrix.h	/^psF32 *psMatrixDeterminant($/;"	p
+psMatrixEigenvectors	include/psMatrix.h	/^psImage* psMatrixEigenvectors($/;"	p
+psMatrixEigenvectors	src/dataManip/psMatrix.c	/^psImage* psMatrixEigenvectors(psImage* outImage, psImage* inImage)$/;"	f
+psMatrixEigenvectors	src/dataManip/psMatrix.h	/^psImage* psMatrixEigenvectors($/;"	p
+psMatrixInvert	include/psMatrix.h	/^psImage* psMatrixInvert($/;"	p
+psMatrixInvert	src/dataManip/psMatrix.c	/^psImage* psMatrixInvert(psImage* outImage, const psImage* inImage, psF32 *det)$/;"	f
+psMatrixInvert	src/dataManip/psMatrix.h	/^psImage* psMatrixInvert($/;"	p
+psMatrixLUD	include/psMatrix.h	/^psImage* psMatrixLUD($/;"	p
+psMatrixLUD	src/dataManip/psMatrix.c	/^psImage* psMatrixLUD(psImage* outImage, psVector* outPerm, psImage* inImage)$/;"	f
+psMatrixLUD	src/dataManip/psMatrix.h	/^psImage* psMatrixLUD($/;"	p
+psMatrixLUD_EXIT	src/dataManip/psMatrix.c	/^    #define psMatrixLUD_EXIT /;"	d	file:
+psMatrixLUSolve	include/psMatrix.h	/^psVector* psMatrixLUSolve($/;"	p
+psMatrixLUSolve	src/dataManip/psMatrix.c	/^psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage, const psVector* inVector,$/;"	f
+psMatrixLUSolve	src/dataManip/psMatrix.h	/^psVector* psMatrixLUSolve($/;"	p
+psMatrixMultiply	include/psMatrix.h	/^psImage* psMatrixMultiply($/;"	p
+psMatrixMultiply	src/dataManip/psMatrix.c	/^psImage* psMatrixMultiply(psImage* outImage, psImage* inImage1, psImage* inImage2)$/;"	f
+psMatrixMultiply	src/dataManip/psMatrix.h	/^psImage* psMatrixMultiply($/;"	p
+psMatrixToVector	include/psMatrix.h	/^psVector* psMatrixToVector($/;"	p
+psMatrixToVector	src/dataManip/psMatrix.c	/^psVector* psMatrixToVector(psVector* outVector, const psImage* inImage)$/;"	f
+psMatrixToVector	src/dataManip/psMatrix.h	/^psVector* psMatrixToVector($/;"	p
+psMatrixToVector_EXIT	src/dataManip/psMatrix.c	/^    #define psMatrixToVector_EXIT /;"	d	file:
+psMatrixTranspose	include/psMatrix.h	/^psImage* psMatrixTranspose($/;"	p
+psMatrixTranspose	src/dataManip/psMatrix.c	/^psImage* psMatrixTranspose(psImage* outImage, const psImage* inImage)$/;"	f
+psMatrixTranspose	src/dataManip/psMatrix.h	/^psImage* psMatrixTranspose($/;"	p
+psMemAllocateCallback	include/psMemory.h	/^typedef psMemoryId(*psMemAllocateCallback) ($/;"	t
+psMemAllocateCallback	src/sysUtils/psMemory.h	/^typedef psMemoryId(*psMemAllocateCallback) ($/;"	t
+psMemAllocateCallbackSet	include/psMemory.h	/^psMemAllocateCallback psMemAllocateCallbackSet($/;"	p
+psMemAllocateCallbackSet	src/sysUtils/psMemory.c	/^psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)$/;"	f
+psMemAllocateCallbackSet	src/sysUtils/psMemory.h	/^psMemAllocateCallback psMemAllocateCallbackSet($/;"	p
+psMemAllocateCallbackSetID	include/psMemory.h	/^psMemoryId psMemAllocateCallbackSetID($/;"	p
+psMemAllocateCallbackSetID	src/sysUtils/psMemory.c	/^psMemoryId psMemAllocateCallbackSetID(psMemoryId id)$/;"	f
+psMemAllocateCallbackSetID	src/sysUtils/psMemory.h	/^psMemoryId psMemAllocateCallbackSetID($/;"	p
+psMemBlock	include/psMemory.h	/^psMemBlock;$/;"	t
+psMemBlock	include/psMemory.h	/^typedef struct psMemBlock$/;"	s
+psMemBlock	src/sysUtils/psMemory.h	/^psMemBlock;$/;"	t
+psMemBlock	src/sysUtils/psMemory.h	/^typedef struct psMemBlock$/;"	s
+psMemCheckCorruption	include/psMemory.h	/^psS32 psMemCheckCorruption($/;"	p
+psMemCheckCorruption	src/sysUtils/psMemory.c	/^psS32 psMemCheckCorruption(psBool abort_on_error)$/;"	f
+psMemCheckCorruption	src/sysUtils/psMemory.h	/^psS32 psMemCheckCorruption($/;"	p
+psMemCheckLeaks	include/psMemory.h	/^psS32 psMemCheckLeaks($/;"	p
+psMemCheckLeaks	src/sysUtils/psMemory.c	/^psS32 psMemCheckLeaks(psMemoryId id0, psMemBlock* ** arr, FILE * fd, psBool persistence)$/;"	f
+psMemCheckLeaks	src/sysUtils/psMemory.h	/^psS32 psMemCheckLeaks($/;"	p
+psMemDecrRefCounter	include/psMemory.h	/^#define psMemDecrRefCounter(/;"	d
+psMemDecrRefCounter	include/psMemory.h	/^psPtr psMemDecrRefCounter($/;"	p
+psMemDecrRefCounter	src/sysUtils/psMemory.h	/^#define psMemDecrRefCounter(/;"	d
+psMemDecrRefCounter	src/sysUtils/psMemory.h	/^psPtr psMemDecrRefCounter($/;"	p
+psMemExhaustedCallback	include/psMemory.h	/^typedef psPtr (*psMemExhaustedCallback) ($/;"	t
+psMemExhaustedCallback	src/sysUtils/psMemory.h	/^typedef psPtr (*psMemExhaustedCallback) ($/;"	t
+psMemExhaustedCallbackSet	include/psMemory.h	/^psMemExhaustedCallback psMemExhaustedCallbackSet($/;"	p
+psMemExhaustedCallbackSet	src/sysUtils/psMemory.c	/^psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)$/;"	f
+psMemExhaustedCallbackSet	src/sysUtils/psMemory.h	/^psMemExhaustedCallback psMemExhaustedCallbackSet($/;"	p
+psMemFreeCallback	include/psMemory.h	/^typedef psMemoryId(*psMemFreeCallback) ($/;"	t
+psMemFreeCallback	src/sysUtils/psMemory.h	/^typedef psMemoryId(*psMemFreeCallback) ($/;"	t
+psMemFreeCallbackSet	include/psMemory.h	/^psMemFreeCallback psMemFreeCallbackSet($/;"	p
+psMemFreeCallbackSet	src/sysUtils/psMemory.c	/^psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)$/;"	f
+psMemFreeCallbackSet	src/sysUtils/psMemory.h	/^psMemFreeCallback psMemFreeCallbackSet($/;"	p
+psMemFreeCallbackSetID	include/psMemory.h	/^psMemoryId psMemFreeCallbackSetID($/;"	p
+psMemFreeCallbackSetID	src/sysUtils/psMemory.c	/^psMemoryId psMemFreeCallbackSetID(psMemoryId id)$/;"	f
+psMemFreeCallbackSetID	src/sysUtils/psMemory.h	/^psMemoryId psMemFreeCallbackSetID($/;"	p
+psMemGetId	include/psMemory.h	/^psMemoryId psMemGetId(void);$/;"	p
+psMemGetId	src/sysUtils/psMemory.c	/^psMemoryId psMemGetId(void)$/;"	f
+psMemGetId	src/sysUtils/psMemory.h	/^psMemoryId psMemGetId(void);$/;"	p
+psMemGetRefCounter	include/psMemory.h	/^psReferenceCount psMemGetRefCounter($/;"	p
+psMemGetRefCounter	src/sysUtils/psMemory.c	/^psReferenceCount psMemGetRefCounter(psPtr vptr)$/;"	f
+psMemGetRefCounter	src/sysUtils/psMemory.h	/^psReferenceCount psMemGetRefCounter($/;"	p
+psMemIncrRefCounter	include/psMemory.h	/^#define psMemIncrRefCounter(/;"	d
+psMemIncrRefCounter	include/psMemory.h	/^psPtr psMemIncrRefCounter($/;"	p
+psMemIncrRefCounter	src/sysUtils/psMemory.h	/^#define psMemIncrRefCounter(/;"	d
+psMemIncrRefCounter	src/sysUtils/psMemory.h	/^psPtr psMemIncrRefCounter($/;"	p
+psMemProblemCallback	include/psMemory.h	/^typedef void (*psMemProblemCallback) ($/;"	t
+psMemProblemCallback	src/sysUtils/psMemory.h	/^typedef void (*psMemProblemCallback) ($/;"	t
+psMemProblemCallbackSet	include/psMemory.h	/^psMemProblemCallback psMemProblemCallbackSet($/;"	p
+psMemProblemCallbackSet	src/sysUtils/psMemory.c	/^psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)$/;"	f
+psMemProblemCallbackSet	src/sysUtils/psMemory.h	/^psMemProblemCallback psMemProblemCallbackSet($/;"	p
+psMemoryId	include/psMemory.h	/^typedef psU64 psMemoryId;$/;"	t
+psMemoryId	src/sysUtils/psMemory.h	/^typedef psU64 psMemoryId;$/;"	t
+psMetadata	include/psMetadata.h	/^psMetadata;$/;"	t
+psMetadata	include/psMetadata.h	/^typedef struct psMetadata$/;"	s
+psMetadata	src/astronomy/psMetadata.h	/^psMetadata;$/;"	t
+psMetadata	src/astronomy/psMetadata.h	/^typedef struct psMetadata$/;"	s
+psMetadataAdd	include/psMetadata.h	/^psBool psMetadataAdd($/;"	p
+psMetadataAdd	src/astronomy/psMetadata.c	/^psBool psMetadataAdd(psMetadata *md, psS32 where, const char *name, psElemType pType,$/;"	f
+psMetadataAdd	src/astronomy/psMetadata.h	/^psBool psMetadataAdd($/;"	p
+psMetadataAddItem	include/psMetadata.h	/^psBool psMetadataAddItem($/;"	p
+psMetadataAddItem	src/astronomy/psMetadata.c	/^psBool psMetadataAddItem(psMetadata *md, psMetadataItem *metadataItem, psS32 location)$/;"	f
+psMetadataAddItem	src/astronomy/psMetadata.h	/^psBool psMetadataAddItem($/;"	p
+psMetadataAlloc	include/psMetadata.h	/^psMetadata* psMetadataAlloc(void);$/;"	p
+psMetadataAlloc	src/astronomy/psMetadata.c	/^psMetadata* psMetadataAlloc(void)$/;"	f
+psMetadataAlloc	src/astronomy/psMetadata.h	/^psMetadata* psMetadataAlloc(void);$/;"	p
+psMetadataGet	include/psMetadata.h	/^psMetadataItem* psMetadataGet($/;"	p
+psMetadataGet	src/astronomy/psMetadata.c	/^psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)$/;"	f
+psMetadataGet	src/astronomy/psMetadata.h	/^psMetadataItem* psMetadataGet($/;"	p
+psMetadataItem	include/psMetadata.h	/^psMetadataItem;$/;"	t
+psMetadataItem	include/psMetadata.h	/^typedef struct psMetadataItem$/;"	s
+psMetadataItem	src/astronomy/psMetadata.h	/^psMetadataItem;$/;"	t
+psMetadataItem	src/astronomy/psMetadata.h	/^typedef struct psMetadataItem$/;"	s
+psMetadataItemAlloc	include/psMetadata.h	/^psMetadataItem* psMetadataItemAlloc($/;"	p
+psMetadataItemAlloc	src/astronomy/psMetadata.c	/^psMetadataItem* psMetadataItemAlloc(const char *name, psElemType pType, psMetadataType type,$/;"	f
+psMetadataItemAlloc	src/astronomy/psMetadata.h	/^psMetadataItem* psMetadataItemAlloc($/;"	p
+psMetadataItemAllocV	include/psMetadata.h	/^psMetadataItem* psMetadataItemAllocV($/;"	p
+psMetadataItemAllocV	src/astronomy/psMetadata.c	/^psMetadataItem* psMetadataItemAllocV(const char *name, psElemType pType, psMetadataType type,$/;"	f
+psMetadataItemAllocV	src/astronomy/psMetadata.h	/^psMetadataItem* psMetadataItemAllocV($/;"	p
+psMetadataItemPrint	include/psMetadataIO.h	/^bool psMetadataItemPrint($/;"	p
+psMetadataItemPrint	src/astronomy/psMetadataIO.c	/^bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem)$/;"	f
+psMetadataItemPrint	src/astronomy/psMetadataIO.h	/^bool psMetadataItemPrint($/;"	p
+psMetadataLookup	include/psMetadata.h	/^psMetadataItem* psMetadataLookup($/;"	p
+psMetadataLookup	src/astronomy/psMetadata.c	/^psMetadataItem* psMetadataLookup(psMetadata *md, const char *key)$/;"	f
+psMetadataLookup	src/astronomy/psMetadata.h	/^psMetadataItem* psMetadataLookup($/;"	p
+psMetadataLookupF64	include/psMetadata.h	/^psF64 psMetadataLookupF64($/;"	p
+psMetadataLookupF64	src/astronomy/psMetadata.c	/^psF64 psMetadataLookupF64(psMetadata *md, const char *key, psU32 *status)$/;"	f
+psMetadataLookupF64	src/astronomy/psMetadata.h	/^psF64 psMetadataLookupF64($/;"	p
+psMetadataLookupPtr	include/psMetadata.h	/^void* psMetadataLookupPtr($/;"	p
+psMetadataLookupPtr	src/astronomy/psMetadata.c	/^void* psMetadataLookupPtr(psMetadata *md, const char *key, psU32 *status)$/;"	f
+psMetadataLookupPtr	src/astronomy/psMetadata.h	/^void* psMetadataLookupPtr($/;"	p
+psMetadataLookupS32	include/psMetadata.h	/^psS32 psMetadataLookupS32($/;"	p
+psMetadataLookupS32	src/astronomy/psMetadata.c	/^psS32 psMetadataLookupS32(psMetadata *md, const char *key, psU32 *status)$/;"	f
+psMetadataLookupS32	src/astronomy/psMetadata.h	/^psS32 psMetadataLookupS32($/;"	p
+psMetadataParseConfig	include/psMetadataIO.h	/^psMetadata* psMetadataParseConfig($/;"	p
+psMetadataParseConfig	src/astronomy/psMetadataIO.c	/^psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)$/;"	f
+psMetadataParseConfig	src/astronomy/psMetadataIO.h	/^psMetadata* psMetadataParseConfig($/;"	p
+psMetadataParseConfigXml	include/psMetadataIO.h	/^psMetadata*  psMetadataParseConfigXml($/;"	p
+psMetadataParseConfigXml	src/astronomy/psMetadataIO.c	/^psMetadata*  psMetadataParseConfigXml(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite)$/;"	f
+psMetadataParseConfigXml	src/astronomy/psMetadataIO.h	/^psMetadata*  psMetadataParseConfigXml($/;"	p
+psMetadataReadHeader	include/psMetadataIO.h	/^psMetadata* psMetadataReadHeader($/;"	p
+psMetadataReadHeader	src/astronomy/psMetadataIO.c	/^psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, psS32 extNum, char *fileName)$/;"	f
+psMetadataReadHeader	src/astronomy/psMetadataIO.h	/^psMetadata* psMetadataReadHeader($/;"	p
+psMetadataRemove	include/psMetadata.h	/^psBool psMetadataRemove($/;"	p
+psMetadataRemove	src/astronomy/psMetadata.c	/^psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key)$/;"	f
+psMetadataRemove	src/astronomy/psMetadata.h	/^psBool psMetadataRemove($/;"	p
+psMetadataType	include/psMetadata.h	/^} psMetadataType;$/;"	t
+psMetadataType	src/astronomy/psMetadata.h	/^} psMetadataType;$/;"	t
+psMinimization	include/psMinimize.h	/^psMinimization;$/;"	t
+psMinimization	src/dataManip/psMinimize.h	/^psMinimization;$/;"	t
+psMinimizationAlloc	include/psMinimize.h	/^psMinimization *psMinimizationAlloc(psS32 maxIter,$/;"	p
+psMinimizationAlloc	src/dataManip/psMinimize.c	/^psMinimization *psMinimizationAlloc(psS32 maxIter,$/;"	f
+psMinimizationAlloc	src/dataManip/psMinimize.h	/^psMinimization *psMinimizationAlloc(psS32 maxIter,$/;"	p
+psMinimizeChi2Powell	include/psMinimize.h	/^psBool psMinimizeChi2Powell(psMinimization *min,$/;"	p
+psMinimizeChi2Powell	src/dataManip/psMinimize.c	/^psBool psMinimizeChi2Powell(psMinimization *min,$/;"	f
+psMinimizeChi2Powell	src/dataManip/psMinimize.h	/^psBool psMinimizeChi2Powell(psMinimization *min,$/;"	p
+psMinimizeChi2PowellFunc	include/psMinimize.h	/^psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,$/;"	t
+psMinimizeChi2PowellFunc	src/dataManip/psMinimize.h	/^psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,$/;"	t
+psMinimizeLMChi2	include/psMinimize.h	/^psBool psMinimizeLMChi2(psMinimization *min,$/;"	p
+psMinimizeLMChi2	src/dataManip/psMinimize.c	/^psBool psMinimizeLMChi2(psMinimization *min,$/;"	f
+psMinimizeLMChi2	src/dataManip/psMinimize.h	/^psBool psMinimizeLMChi2(psMinimization *min,$/;"	p
+psMinimizeLMChi2Func	include/psMinimize.h	/^psVector* (*psMinimizeLMChi2Func)(psImage *deriv,$/;"	t
+psMinimizeLMChi2Func	src/dataManip/psMinimize.h	/^psVector* (*psMinimizeLMChi2Func)(psImage *deriv,$/;"	t
+psMinimizeLMChi2Gauss1D	include/psMinimize.h	/^psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,$/;"	p
+psMinimizeLMChi2Gauss1D	src/dataManip/psMinimize.c	/^psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,$/;"	f
+psMinimizeLMChi2Gauss1D	src/dataManip/psMinimize.h	/^psVector *psMinimizeLMChi2Gauss1D(psImage *deriv,$/;"	p
+psMinimizeLMChi2Gauss2D	src/dataManip/psMinimize.c	/^psVector *psMinimizeLMChi2Gauss2D(psImage *deriv,$/;"	f
+psMinimizePowell	include/psMinimize.h	/^psBool psMinimizePowell(psMinimization *min,$/;"	p
+psMinimizePowell	src/dataManip/psMinimize.c	/^psBool psMinimizePowell(psMinimization *min,$/;"	f
+psMinimizePowell	src/dataManip/psMinimize.h	/^psBool psMinimizePowell(psMinimization *min,$/;"	p
+psMinimizePowellChi2Gauss1D	include/psMinimize.h	/^psVector *psMinimizePowellChi2Gauss1D(const psVector *params,$/;"	p
+psMinimizePowellChi2Gauss1D	src/dataManip/psMinimize.c	/^psVector *psMinimizePowellChi2Gauss1D(const psVector *params,$/;"	f
+psMinimizePowellChi2Gauss1D	src/dataManip/psMinimize.h	/^psVector *psMinimizePowellChi2Gauss1D(const psVector *params,$/;"	p
+psMinimizePowellFunc	include/psMinimize.h	/^psF32 (*psMinimizePowellFunc)(const psVector *params,$/;"	t
+psMinimizePowellFunc	src/dataManip/psMinimize.h	/^psF32 (*psMinimizePowellFunc)(const psVector *params,$/;"	t
+psObservatory	include/psAstrometry.h	/^psObservatory;$/;"	t
+psObservatory	src/astronomy/psAstrometry.h	/^psObservatory;$/;"	t
+psObservatoryAlloc	include/psAstrometry.h	/^psObservatory* psObservatoryAlloc($/;"	p
+psObservatoryAlloc	src/astronomy/psAstrometry.c	/^psObservatory* psObservatoryAlloc(const char* name,$/;"	f
+psObservatoryAlloc	src/astronomy/psAstrometry.h	/^psObservatory* psObservatoryAlloc($/;"	p
+psParseErrorType	include/psLookupTable.h	/^}psParseErrorType;$/;"	t
+psParseErrorType	src/fileUtils/psLookupTable.h	/^}psParseErrorType;$/;"	t
+psPhotSystem	include/psPhotometry.h	/^psPhotSystem;$/;"	t
+psPhotSystem	src/astronomy/psPhotometry.h	/^psPhotSystem;$/;"	t
+psPhotTransform	include/psPhotometry.h	/^psPhotTransform;$/;"	t
+psPhotTransform	src/astronomy/psPhotometry.h	/^psPhotTransform;$/;"	t
+psPlane	include/psCoord.h	/^psPlane;$/;"	t
+psPlane	src/astronomy/psCoord.h	/^psPlane;$/;"	t
+psPlaneDistort	include/psCoord.h	/^psPlaneDistort;$/;"	t
+psPlaneDistort	src/astronomy/psCoord.h	/^psPlaneDistort;$/;"	t
+psPlaneDistortAlloc	include/psCoord.h	/^psPlaneDistort* psPlaneDistortAlloc($/;"	p
+psPlaneDistortAlloc	src/astronomy/psCoord.c	/^psPlaneDistort* psPlaneDistortAlloc(psS32 n1, psS32 n2, psS32 n3, psS32 n4)$/;"	f
+psPlaneDistortAlloc	src/astronomy/psCoord.h	/^psPlaneDistort* psPlaneDistortAlloc($/;"	p
+psPlaneDistortApply	include/psCoord.h	/^psPlane* psPlaneDistortApply($/;"	p
+psPlaneDistortApply	src/astronomy/psCoord.c	/^psPlane* psPlaneDistortApply(psPlane* out,$/;"	f
+psPlaneDistortApply	src/astronomy/psCoord.h	/^psPlane* psPlaneDistortApply($/;"	p
+psPlaneDistortFree	test/astronomy/tst_psAstrometry01.c	/^static void psPlaneDistortFree(psPlaneDistort *pd)$/;"	f	file:
+psPlaneTransform	include/psCoord.h	/^psPlaneTransform;$/;"	t
+psPlaneTransform	src/astronomy/psCoord.h	/^psPlaneTransform;$/;"	t
+psPlaneTransformAlloc	include/psCoord.h	/^psPlaneTransform* psPlaneTransformAlloc($/;"	p
+psPlaneTransformAlloc	src/astronomy/psCoord.c	/^psPlaneTransform* psPlaneTransformAlloc(psS32 n1, psS32 n2)$/;"	f
+psPlaneTransformAlloc	src/astronomy/psCoord.h	/^psPlaneTransform* psPlaneTransformAlloc($/;"	p
+psPlaneTransformApply	include/psCoord.h	/^psPlane* psPlaneTransformApply($/;"	p
+psPlaneTransformApply	src/astronomy/psCoord.c	/^psPlane* psPlaneTransformApply(psPlane* out,$/;"	f
+psPlaneTransformApply	src/astronomy/psCoord.h	/^psPlane* psPlaneTransformApply($/;"	p
+psPlaneTransformFree	test/astronomy/tst_psAstrometry01.c	/^static void psPlaneTransformFree(psPlaneTransform *pd)$/;"	f	file:
+psPolynomial1D	include/psFunctions.h	/^psPolynomial1D;$/;"	t
+psPolynomial1D	src/dataManip/psFunctions.h	/^psPolynomial1D;$/;"	t
+psPolynomial1DAlloc	include/psFunctions.h	/^psPolynomial1D* psPolynomial1DAlloc($/;"	p
+psPolynomial1DAlloc	src/dataManip/psFunctions.c	/^psPolynomial1D* psPolynomial1DAlloc(psS32 n,$/;"	f
+psPolynomial1DAlloc	src/dataManip/psFunctions.h	/^psPolynomial1D* psPolynomial1DAlloc($/;"	p
+psPolynomial1DEval	include/psFunctions.h	/^psF32 psPolynomial1DEval($/;"	p
+psPolynomial1DEval	src/dataManip/psFunctions.c	/^psF32 psPolynomial1DEval(const psPolynomial1D* myPoly, psF32 x)$/;"	f
+psPolynomial1DEval	src/dataManip/psFunctions.h	/^psF32 psPolynomial1DEval($/;"	p
+psPolynomial1DEvalVector	include/psFunctions.h	/^psVector *psPolynomial1DEvalVector($/;"	p
+psPolynomial1DEvalVector	src/dataManip/psFunctions.c	/^psVector *psPolynomial1DEvalVector(const psPolynomial1D *myPoly,$/;"	f
+psPolynomial1DEvalVector	src/dataManip/psFunctions.h	/^psVector *psPolynomial1DEvalVector($/;"	p
+psPolynomial2D	include/psFunctions.h	/^psPolynomial2D;$/;"	t
+psPolynomial2D	src/dataManip/psFunctions.h	/^psPolynomial2D;$/;"	t
+psPolynomial2DAlloc	include/psFunctions.h	/^psPolynomial2D* psPolynomial2DAlloc($/;"	p
+psPolynomial2DAlloc	src/dataManip/psFunctions.c	/^psPolynomial2D* psPolynomial2DAlloc(psS32 nX, psS32 nY,$/;"	f
+psPolynomial2DAlloc	src/dataManip/psFunctions.h	/^psPolynomial2D* psPolynomial2DAlloc($/;"	p
+psPolynomial2DEval	include/psFunctions.h	/^psF32 psPolynomial2DEval($/;"	p
+psPolynomial2DEval	src/dataManip/psFunctions.c	/^psF32 psPolynomial2DEval(const psPolynomial2D* myPoly, psF32 x, psF32 y)$/;"	f
+psPolynomial2DEval	src/dataManip/psFunctions.h	/^psF32 psPolynomial2DEval($/;"	p
+psPolynomial2DEvalVector	include/psFunctions.h	/^psVector *psPolynomial2DEvalVector($/;"	p
+psPolynomial2DEvalVector	src/dataManip/psFunctions.c	/^psVector *psPolynomial2DEvalVector(const psPolynomial2D *myPoly,$/;"	f
+psPolynomial2DEvalVector	src/dataManip/psFunctions.h	/^psVector *psPolynomial2DEvalVector($/;"	p
+psPolynomial3D	include/psFunctions.h	/^psPolynomial3D;$/;"	t
+psPolynomial3D	src/dataManip/psFunctions.h	/^psPolynomial3D;$/;"	t
+psPolynomial3DAlloc	include/psFunctions.h	/^psPolynomial3D* psPolynomial3DAlloc($/;"	p
+psPolynomial3DAlloc	src/dataManip/psFunctions.c	/^psPolynomial3D* psPolynomial3DAlloc(psS32 nX, psS32 nY, psS32 nZ,$/;"	f
+psPolynomial3DAlloc	src/dataManip/psFunctions.h	/^psPolynomial3D* psPolynomial3DAlloc($/;"	p
+psPolynomial3DEval	include/psFunctions.h	/^psF32 psPolynomial3DEval($/;"	p
+psPolynomial3DEval	src/dataManip/psFunctions.c	/^psF32 psPolynomial3DEval(const psPolynomial3D* myPoly, psF32 x, psF32 y, psF32 z)$/;"	f
+psPolynomial3DEval	src/dataManip/psFunctions.h	/^psF32 psPolynomial3DEval($/;"	p
+psPolynomial3DEvalVector	include/psFunctions.h	/^psVector *psPolynomial3DEvalVector($/;"	p
+psPolynomial3DEvalVector	src/dataManip/psFunctions.c	/^psVector *psPolynomial3DEvalVector(const psPolynomial3D *myPoly,$/;"	f
+psPolynomial3DEvalVector	src/dataManip/psFunctions.h	/^psVector *psPolynomial3DEvalVector($/;"	p
+psPolynomial4D	include/psFunctions.h	/^psPolynomial4D;$/;"	t
+psPolynomial4D	src/dataManip/psFunctions.h	/^psPolynomial4D;$/;"	t
+psPolynomial4DAlloc	include/psFunctions.h	/^psPolynomial4D* psPolynomial4DAlloc($/;"	p
+psPolynomial4DAlloc	src/dataManip/psFunctions.c	/^psPolynomial4D* psPolynomial4DAlloc(psS32 nW, psS32 nX, psS32 nY, psS32 nZ,$/;"	f
+psPolynomial4DAlloc	src/dataManip/psFunctions.h	/^psPolynomial4D* psPolynomial4DAlloc($/;"	p
+psPolynomial4DEval	include/psFunctions.h	/^psF32 psPolynomial4DEval($/;"	p
+psPolynomial4DEval	src/dataManip/psFunctions.c	/^psF32 psPolynomial4DEval(const psPolynomial4D* myPoly, psF32 w, psF32 x, psF32 y, psF32 z)$/;"	f
+psPolynomial4DEval	src/dataManip/psFunctions.h	/^psF32 psPolynomial4DEval($/;"	p
+psPolynomial4DEvalVector	include/psFunctions.h	/^psVector *psPolynomial4DEvalVector($/;"	p
+psPolynomial4DEvalVector	src/dataManip/psFunctions.c	/^psVector *psPolynomial4DEvalVector(const psPolynomial4D *myPoly,$/;"	f
+psPolynomial4DEvalVector	src/dataManip/psFunctions.h	/^psVector *psPolynomial4DEvalVector($/;"	p
+psPolynomialType	include/psFunctions.h	/^} psPolynomialType;$/;"	t
+psPolynomialType	src/dataManip/psFunctions.h	/^} psPolynomialType;$/;"	t
+psProject	include/psCoord.h	/^psPlane* psProject($/;"	p
+psProject	src/astronomy/psCoord.c	/^psPlane* psProject(const psSphere* coord,$/;"	f
+psProject	src/astronomy/psCoord.h	/^psPlane* psProject($/;"	p
+psProjection	include/psCoord.h	/^psProjection;$/;"	t
+psProjection	src/astronomy/psCoord.h	/^psProjection;$/;"	t
+psProjectionType	include/psCoord.h	/^} psProjectionType;$/;"	t
+psProjectionType	src/astronomy/psCoord.h	/^} psProjectionType;$/;"	t
+psPtr	include/psType.h	/^typedef void* psPtr;                   \/\/\/< void pointer$/;"	t
+psPtr	src/sysUtils/psType.h	/^typedef void* psPtr;                   \/\/\/< void pointer$/;"	t
+psRandom	include/psRandom.h	/^psRandom;$/;"	t
+psRandom	src/dataManip/psRandom.h	/^psRandom;$/;"	t
+psRandomAlloc	include/psRandom.h	/^psRandom *psRandomAlloc(psRandomType type,$/;"	p
+psRandomAlloc	src/dataManip/psRandom.c	/^psRandom *psRandomAlloc(psRandomType type,$/;"	f
+psRandomAlloc	src/dataManip/psRandom.h	/^psRandom *psRandomAlloc(psRandomType type,$/;"	p
+psRandomGaussian	include/psRandom.h	/^psF64 psRandomGaussian(const psRandom *r);$/;"	p
+psRandomGaussian	src/dataManip/psRandom.c	/^psF64 psRandomGaussian(const psRandom *r)$/;"	f
+psRandomGaussian	src/dataManip/psRandom.h	/^psF64 psRandomGaussian(const psRandom *r);$/;"	p
+psRandomPoisson	include/psRandom.h	/^psF64 psRandomPoisson(const psRandom *r, psF64 mean);$/;"	p
+psRandomPoisson	src/dataManip/psRandom.c	/^psF64 psRandomPoisson(const psRandom *r, psF64 mean)$/;"	f
+psRandomPoisson	src/dataManip/psRandom.h	/^psF64 psRandomPoisson(const psRandom *r, psF64 mean);$/;"	p
+psRandomReset	include/psRandom.h	/^void psRandomReset(psRandom *rand,$/;"	p
+psRandomReset	src/dataManip/psRandom.c	/^void psRandomReset(psRandom *rand,$/;"	f
+psRandomReset	src/dataManip/psRandom.h	/^void psRandomReset(psRandom *rand,$/;"	p
+psRandomType	include/psRandom.h	/^} psRandomType;$/;"	t
+psRandomType	src/dataManip/psRandom.h	/^} psRandomType;$/;"	t
+psRandomUniform	include/psRandom.h	/^psF64 psRandomUniform(const psRandom *r);$/;"	p
+psRandomUniform	src/dataManip/psRandom.c	/^psF64 psRandomUniform(const psRandom *r)$/;"	f
+psRandomUniform	src/dataManip/psRandom.h	/^psF64 psRandomUniform(const psRandom *r);$/;"	p
+psReadout	include/psAstrometry.h	/^psReadout;$/;"	t
+psReadout	src/astronomy/psAstrometry.h	/^psReadout;$/;"	t
+psReadoutAlloc	include/psAstrometry.h	/^psReadout* psReadoutAlloc($/;"	p
+psReadoutAlloc	src/astronomy/psAstrometry.c	/^psReadout* psReadoutAlloc(psS32 col0,$/;"	f
+psReadoutAlloc	src/astronomy/psAstrometry.h	/^psReadout* psReadoutAlloc($/;"	p
+psRealloc	include/psMemory.h	/^#define psRealloc(/;"	d
+psRealloc	include/psMemory.h	/^psPtr psRealloc($/;"	p
+psRealloc	src/sysUtils/psMemory.h	/^#define psRealloc(/;"	d
+psRealloc	src/sysUtils/psMemory.h	/^psPtr psRealloc($/;"	p
+psReferenceCount	include/psMemory.h	/^typedef psU64 psReferenceCount;$/;"	t
+psReferenceCount	src/sysUtils/psMemory.h	/^typedef psU64 psReferenceCount;$/;"	t
+psRegion	include/psImage.h	/^psRegion;$/;"	t
+psRegion	src/image/psImage.h	/^psRegion;$/;"	t
+psRegionAlloc	include/psImage.h	/^psRegion* psRegionAlloc($/;"	p
+psRegionAlloc	src/image/psImage.c	/^psRegion* psRegionAlloc(double x0,$/;"	f
+psRegionAlloc	src/image/psImage.h	/^psRegion* psRegionAlloc($/;"	p
+psRegionFromString	include/psImage.h	/^psRegion* psRegionFromString($/;"	p
+psRegionFromString	src/image/psImage.c	/^psRegion* psRegionFromString(char* region)$/;"	f
+psRegionFromString	src/image/psImage.h	/^psRegion* psRegionFromString($/;"	p
+psS16	include/psType.h	/^typedef int16_t psS16;                 \/\/\/< 16-bit signed int$/;"	t
+psS16	src/sysUtils/psType.h	/^typedef int16_t psS16;                 \/\/\/< 16-bit signed int$/;"	t
+psS32	include/psType.h	/^typedef int32_t psS32;                 \/\/\/< 32-bit signed int$/;"	t
+psS32	src/sysUtils/psType.h	/^typedef int32_t psS32;                 \/\/\/< 32-bit signed int$/;"	t
+psS64	include/psType.h	/^typedef int64_t psS64;                 \/\/\/< 64-bit signed int$/;"	t
+psS64	src/sysUtils/psType.h	/^typedef int64_t psS64;                 \/\/\/< 64-bit signed int$/;"	t
+psS8	include/psType.h	/^typedef int8_t psS8;                   \/\/\/< 8-bit signed int$/;"	t
+psS8	src/sysUtils/psType.h	/^typedef int8_t psS8;                   \/\/\/< 8-bit signed int$/;"	t
+psScalar	include/psScalar.h	/^psScalar;$/;"	t
+psScalar	src/collections/psScalar.h	/^psScalar;$/;"	t
+psScalarAlloc	include/psScalar.h	/^psScalar* psScalarAlloc($/;"	p
+psScalarAlloc	src/collections/psScalar.c	/^psScalar* psScalarAlloc(psC64 value, psElemType dataType)$/;"	f
+psScalarAlloc	src/collections/psScalar.h	/^psScalar* psScalarAlloc($/;"	p
+psScalarCopy	include/psScalar.h	/^psScalar* psScalarCopy($/;"	p
+psScalarCopy	src/collections/psScalar.c	/^psScalar* psScalarCopy(psScalar *scalar)$/;"	f
+psScalarCopy	src/collections/psScalar.h	/^psScalar* psScalarCopy($/;"	p
+psSphere	include/psCoord.h	/^psSphere;$/;"	t
+psSphere	include/psCoord.h	/^typedef struct psSphere$/;"	s
+psSphere	src/astronomy/psCoord.h	/^psSphere;$/;"	t
+psSphere	src/astronomy/psCoord.h	/^typedef struct psSphere$/;"	s
+psSphereGetOffset	include/psCoord.h	/^psSphere* psSphereGetOffset($/;"	p
+psSphereGetOffset	src/astronomy/psCoord.c	/^psSphere* psSphereGetOffset(const psSphere* restrict position1,$/;"	f
+psSphereGetOffset	src/astronomy/psCoord.h	/^psSphere* psSphereGetOffset($/;"	p
+psSphereOffsetMode	include/psCoord.h	/^} psSphereOffsetMode;$/;"	t
+psSphereOffsetMode	src/astronomy/psCoord.h	/^} psSphereOffsetMode;$/;"	t
+psSphereOffsetUnit	include/psCoord.h	/^} psSphereOffsetUnit;$/;"	t
+psSphereOffsetUnit	src/astronomy/psCoord.h	/^} psSphereOffsetUnit;$/;"	t
+psSpherePrecess	include/psCoord.h	/^psSphere *psSpherePrecess(psSphere *coords,$/;"	p
+psSpherePrecess	src/astronomy/psCoord.c	/^psSphere *psSpherePrecess(psSphere *coords,$/;"	f
+psSpherePrecess	src/astronomy/psCoord.h	/^psSphere *psSpherePrecess(psSphere *coords,$/;"	p
+psSphereSetOffset	include/psCoord.h	/^psSphere* psSphereSetOffset($/;"	p
+psSphereSetOffset	src/astronomy/psCoord.c	/^psSphere* psSphereSetOffset(const psSphere* restrict position,$/;"	f
+psSphereSetOffset	src/astronomy/psCoord.h	/^psSphere* psSphereSetOffset($/;"	p
+psSphereTransform	include/psCoord.h	/^psSphereTransform;$/;"	t
+psSphereTransform	src/astronomy/psCoord.h	/^psSphereTransform;$/;"	t
+psSphereTransformAlloc	include/psCoord.h	/^psSphereTransform* psSphereTransformAlloc($/;"	p
+psSphereTransformAlloc	src/astronomy/psCoord.c	/^psSphereTransform* psSphereTransformAlloc(psF64 alphaP,$/;"	f
+psSphereTransformAlloc	src/astronomy/psCoord.h	/^psSphereTransform* psSphereTransformAlloc($/;"	p
+psSphereTransformApply	include/psCoord.h	/^psSphere* psSphereTransformApply($/;"	p
+psSphereTransformApply	src/astronomy/psCoord.c	/^psSphere* psSphereTransformApply(psSphere* out,$/;"	f
+psSphereTransformApply	src/astronomy/psCoord.h	/^psSphere* psSphereTransformApply($/;"	p
+psSphereTransformEclipticToICRS	include/psCoord.h	/^psSphereTransform* psSphereTransformEclipticToICRS($/;"	p
+psSphereTransformEclipticToICRS	src/astronomy/psCoord.c	/^psSphereTransform* psSphereTransformEclipticToICRS(psTime *time)$/;"	f
+psSphereTransformEclipticToICRS	src/astronomy/psCoord.h	/^psSphereTransform* psSphereTransformEclipticToICRS($/;"	p
+psSphereTransformGalaticToICRS	include/psCoord.h	/^psSphereTransform* psSphereTransformGalaticToICRS(void);$/;"	p
+psSphereTransformGalaticToICRS	src/astronomy/psCoord.c	/^psSphereTransform* psSphereTransformGalaticToICRS(void)$/;"	f
+psSphereTransformGalaticToICRS	src/astronomy/psCoord.h	/^psSphereTransform* psSphereTransformGalaticToICRS(void);$/;"	p
+psSphereTransformICRSToEcliptic	include/psCoord.h	/^psSphereTransform* psSphereTransformICRSToEcliptic($/;"	p
+psSphereTransformICRSToEcliptic	src/astronomy/psCoord.c	/^psSphereTransform* psSphereTransformICRSToEcliptic(psTime *time)$/;"	f
+psSphereTransformICRSToEcliptic	src/astronomy/psCoord.h	/^psSphereTransform* psSphereTransformICRSToEcliptic($/;"	p
+psSphereTransformICRSToGalatic	include/psCoord.h	/^psSphereTransform* psSphereTransformICRSToGalatic(void);$/;"	p
+psSphereTransformICRSToGalatic	src/astronomy/psCoord.c	/^psSphereTransform* psSphereTransformICRSToGalatic(void)$/;"	f
+psSphereTransformICRSToGalatic	src/astronomy/psCoord.h	/^psSphereTransform* psSphereTransformICRSToGalatic(void);$/;"	p
+psSpline1D	include/psFunctions.h	/^psSpline1D;$/;"	t
+psSpline1D	src/dataManip/psFunctions.h	/^psSpline1D;$/;"	t
+psSpline1DAlloc	include/psFunctions.h	/^psSpline1D *psSpline1DAlloc(psS32 n,$/;"	p
+psSpline1DAlloc	src/dataManip/psFunctions.c	/^psSpline1D *psSpline1DAlloc(psS32 numSplines,$/;"	f
+psSpline1DAlloc	src/dataManip/psFunctions.h	/^psSpline1D *psSpline1DAlloc(psS32 n,$/;"	p
+psSpline1DAllocGeneric	include/psFunctions.h	/^psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,$/;"	p
+psSpline1DAllocGeneric	src/dataManip/psFunctions.c	/^psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,$/;"	f
+psSpline1DAllocGeneric	src/dataManip/psFunctions.h	/^psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,$/;"	p
+psSpline1DEval	include/psFunctions.h	/^psF32 psSpline1DEval($/;"	p
+psSpline1DEval	src/dataManip/psFunctions.c	/^psF32 psSpline1DEval($/;"	f
+psSpline1DEval	src/dataManip/psFunctions.h	/^psF32 psSpline1DEval($/;"	p
+psSpline1DEvalVector	include/psFunctions.h	/^psVector *psSpline1DEvalVector($/;"	p
+psSpline1DEvalVector	src/dataManip/psFunctions.c	/^psVector *psSpline1DEvalVector($/;"	f
+psSpline1DEvalVector	src/dataManip/psFunctions.h	/^psVector *psSpline1DEvalVector($/;"	p
+psStats	include/psStats.h	/^psStats;$/;"	t
+psStats	src/dataManip/psStats.h	/^psStats;$/;"	t
+psStatsAlloc	include/psStats.h	/^psStats* psStatsAlloc($/;"	p
+psStatsAlloc	src/dataManip/psStats.c	/^psStats* psStatsAlloc(psStatsOptions options)$/;"	f
+psStatsAlloc	src/dataManip/psStats.h	/^psStats* psStatsAlloc($/;"	p
+psStatsOptions	include/psStats.h	/^} psStatsOptions;$/;"	t
+psStatsOptions	src/dataManip/psStats.h	/^} psStatsOptions;$/;"	t
+psStringCopy	include/psString.h	/^char *psStringCopy($/;"	p
+psStringCopy	src/sysUtils/psString.c	/^char *psStringCopy(const char *str)$/;"	f
+psStringCopy	src/sysUtils/psString.h	/^char *psStringCopy($/;"	p
+psStringNCopy	include/psString.h	/^char *psStringNCopy($/;"	p
+psStringNCopy	src/sysUtils/psString.c	/^char *psStringNCopy(const char *str, psS32 nChar)$/;"	f
+psStringNCopy	src/sysUtils/psString.h	/^char *psStringNCopy($/;"	p
+psTime	include/psTime.h	/^psTime;$/;"	t
+psTime	include/psTime.h	/^typedef struct psTime$/;"	s
+psTime	src/astronomy/psTime.h	/^psTime;$/;"	t
+psTime	src/astronomy/psTime.h	/^typedef struct psTime$/;"	s
+psTimeAlloc	include/psTime.h	/^psTime* psTimeAlloc($/;"	p
+psTimeAlloc	src/astronomy/psTime.c	/^psTime* psTimeAlloc(psTimeType type)$/;"	f
+psTimeAlloc	src/astronomy/psTime.h	/^psTime* psTimeAlloc($/;"	p
+psTimeConvert	include/psTime.h	/^psTime* psTimeConvert($/;"	p
+psTimeConvert	src/astronomy/psTime.c	/^psTime* psTimeConvert(psTime *time, psTimeType type)$/;"	f
+psTimeConvert	src/astronomy/psTime.h	/^psTime* psTimeConvert($/;"	p
+psTimeDelta	include/psTime.h	/^psF64 psTimeDelta($/;"	p
+psTimeDelta	src/astronomy/psTime.c	/^psF64 psTimeDelta(const psTime *time1, const psTime *time2)$/;"	f
+psTimeDelta	src/astronomy/psTime.h	/^psF64 psTimeDelta($/;"	p
+psTimeFromISOTime	include/psTime.h	/^psTime* psTimeFromISOTime($/;"	p
+psTimeFromISOTime	src/astronomy/psTime.c	/^psTime* psTimeFromISOTime(const char *time)$/;"	f
+psTimeFromISOTime	src/astronomy/psTime.h	/^psTime* psTimeFromISOTime($/;"	p
+psTimeFromJD	include/psTime.h	/^psTime* psTimeFromJD($/;"	p
+psTimeFromJD	src/astronomy/psTime.c	/^psTime* psTimeFromJD(double time)$/;"	f
+psTimeFromJD	src/astronomy/psTime.h	/^psTime* psTimeFromJD($/;"	p
+psTimeFromMJD	include/psTime.h	/^psTime* psTimeFromMJD($/;"	p
+psTimeFromMJD	src/astronomy/psTime.c	/^psTime* psTimeFromMJD(double time)$/;"	f
+psTimeFromMJD	src/astronomy/psTime.h	/^psTime* psTimeFromMJD($/;"	p
+psTimeFromTM	include/psTime.h	/^psTime* psTimeFromTM($/;"	p
+psTimeFromTM	src/astronomy/psTime.c	/^psTime* psTimeFromTM(const struct tm* time)$/;"	f
+psTimeFromTM	src/astronomy/psTime.h	/^psTime* psTimeFromTM($/;"	p
+psTimeFromTimeval	include/psTime.h	/^psTime* psTimeFromTimeval($/;"	p
+psTimeFromTimeval	src/astronomy/psTime.c	/^psTime* psTimeFromTimeval(const struct timeval *time)$/;"	f
+psTimeFromTimeval	src/astronomy/psTime.h	/^psTime* psTimeFromTimeval($/;"	p
+psTimeGetPoleCoords	include/psTime.h	/^struct psSphere* psTimeGetPoleCoords($/;"	p
+psTimeGetPoleCoords	src/astronomy/psTime.c	/^struct psSphere* psTimeGetPoleCoords(const psTime* time)$/;"	f
+psTimeGetPoleCoords	src/astronomy/psTime.h	/^struct psSphere* psTimeGetPoleCoords($/;"	p
+psTimeGetTAIDelta	include/psTime.h	/^double psTimeGetTAIDelta($/;"	p
+psTimeGetTAIDelta	src/astronomy/psTime.c	/^double psTimeGetTAIDelta(const psTime *time)$/;"	f
+psTimeGetTAIDelta	src/astronomy/psTime.h	/^double psTimeGetTAIDelta($/;"	p
+psTimeGetTime	include/psTime.h	/^psTime* psTimeGetTime($/;"	p
+psTimeGetTime	src/astronomy/psTime.c	/^psTime* psTimeGetTime(psTimeType type)$/;"	f
+psTimeGetTime	src/astronomy/psTime.h	/^psTime* psTimeGetTime($/;"	p
+psTimeGetUT1Delta	include/psTime.h	/^double psTimeGetUT1Delta($/;"	p
+psTimeGetUT1Delta	src/astronomy/psTime.c	/^double psTimeGetUT1Delta(const psTime *time)$/;"	f
+psTimeGetUT1Delta	src/astronomy/psTime.h	/^double psTimeGetUT1Delta($/;"	p
+psTimeLeapseconds	include/psTime.h	/^psS64 psTimeLeapseconds($/;"	p
+psTimeLeapseconds	src/astronomy/psTime.c	/^psS64 psTimeLeapseconds(const psTime *time1, const psTime *time2)$/;"	f
+psTimeLeapseconds	src/astronomy/psTime.h	/^psS64 psTimeLeapseconds($/;"	p
+psTimeMath	include/psTime.h	/^psTime* psTimeMath($/;"	p
+psTimeMath	src/astronomy/psTime.c	/^psTime* psTimeMath(const psTime *time, psF64 delta)$/;"	f
+psTimeMath	src/astronomy/psTime.h	/^psTime* psTimeMath($/;"	p
+psTimeToISOTime	include/psTime.h	/^char* psTimeToISOTime($/;"	p
+psTimeToISOTime	src/astronomy/psTime.c	/^char* psTimeToISOTime(const psTime *time)$/;"	f
+psTimeToISOTime	src/astronomy/psTime.h	/^char* psTimeToISOTime($/;"	p
+psTimeToJD	include/psTime.h	/^double psTimeToJD($/;"	p
+psTimeToJD	src/astronomy/psTime.c	/^double psTimeToJD(const psTime *time)$/;"	f
+psTimeToJD	src/astronomy/psTime.h	/^double psTimeToJD($/;"	p
+psTimeToLST	include/psTime.h	/^double psTimeToLST($/;"	p
+psTimeToLST	src/astronomy/psTime.c	/^double psTimeToLST(psTime *time, double longitude)$/;"	f
+psTimeToLST	src/astronomy/psTime.h	/^double psTimeToLST($/;"	p
+psTimeToMJD	include/psTime.h	/^double psTimeToMJD($/;"	p
+psTimeToMJD	src/astronomy/psTime.c	/^double psTimeToMJD(const psTime *time)$/;"	f
+psTimeToMJD	src/astronomy/psTime.h	/^double psTimeToMJD($/;"	p
+psTimeToTM	include/psTime.h	/^struct tm* psTimeToTM($/;"	p
+psTimeToTM	src/astronomy/psTime.c	/^struct tm* psTimeToTM(const psTime *time)$/;"	f
+psTimeToTM	src/astronomy/psTime.h	/^struct tm* psTimeToTM($/;"	p
+psTimeToTimeval	include/psTime.h	/^struct timeval psTimeToTimeval($/;"	p
+psTimeToTimeval	src/astronomy/psTime.c	/^struct timeval psTimeToTimeval(const psTime *time)$/;"	f
+psTimeToTimeval	src/astronomy/psTime.h	/^struct timeval psTimeToTimeval($/;"	p
+psTimeType	include/psTime.h	/^} psTimeType;$/;"	t
+psTimeType	src/astronomy/psTime.h	/^} psTimeType;$/;"	t
+psTrace	include/psTrace.h	/^#        define psTrace(/;"	d
+psTrace	include/psTrace.h	/^#define psTrace(/;"	d
+psTrace	src/sysUtils/psTrace.h	/^#        define psTrace(/;"	d
+psTrace	src/sysUtils/psTrace.h	/^#define psTrace(/;"	d
+psTraceFree	include/psTrace.h	/^#        define psTraceFree(/;"	d
+psTraceFree	include/psTrace.h	/^void psTraceFree();$/;"	p
+psTraceFree	src/sysUtils/psTrace.h	/^#        define psTraceFree(/;"	d
+psTraceFree	src/sysUtils/psTrace.h	/^void psTraceFree();$/;"	p
+psTraceGetLevel	include/psTrace.h	/^#        define psTraceGetLevel(/;"	d
+psTraceGetLevel	include/psTrace.h	/^psS32 psTraceGetLevel(const char *facil)     \/\/\/< facilty of interest$/;"	p
+psTraceGetLevel	src/sysUtils/psTrace.c	/^psS32 psTraceGetLevel(const char *name)$/;"	f
+psTraceGetLevel	src/sysUtils/psTrace.h	/^#        define psTraceGetLevel(/;"	d
+psTraceGetLevel	src/sysUtils/psTrace.h	/^psS32 psTraceGetLevel(const char *facil)     \/\/\/< facilty of interest$/;"	p
+psTracePrintLevels	include/psTrace.h	/^#        define psTracePrintLevels(/;"	d
+psTracePrintLevels	include/psTrace.h	/^void psTracePrintLevels(void);$/;"	p
+psTracePrintLevels	src/sysUtils/psTrace.c	/^void psTracePrintLevels(void)$/;"	f
+psTracePrintLevels	src/sysUtils/psTrace.h	/^#        define psTracePrintLevels(/;"	d
+psTracePrintLevels	src/sysUtils/psTrace.h	/^void psTracePrintLevels(void);$/;"	p
+psTraceReset	include/psTrace.h	/^#        define psTraceReset(/;"	d
+psTraceReset	include/psTrace.h	/^void psTraceReset();$/;"	p
+psTraceReset	src/sysUtils/psTrace.c	/^void psTraceReset()$/;"	f
+psTraceReset	src/sysUtils/psTrace.h	/^#        define psTraceReset(/;"	d
+psTraceReset	src/sysUtils/psTrace.h	/^void psTraceReset();$/;"	p
+psTraceSetDestination	include/psTrace.h	/^#        define psTraceSetDestination(/;"	d
+psTraceSetDestination	include/psTrace.h	/^void psTraceSetDestination(FILE * fp);$/;"	p
+psTraceSetDestination	src/sysUtils/psTrace.c	/^void psTraceSetDestination(FILE * fp)$/;"	f
+psTraceSetDestination	src/sysUtils/psTrace.h	/^#        define psTraceSetDestination(/;"	d
+psTraceSetDestination	src/sysUtils/psTrace.h	/^void psTraceSetDestination(FILE * fp);$/;"	p
+psTraceSetLevel	include/psTrace.h	/^#        define psTraceSetLevel(/;"	d
+psTraceSetLevel	include/psTrace.h	/^psBool psTraceSetLevel(const char *facil,     \/\/\/< facilty of interest$/;"	p
+psTraceSetLevel	src/sysUtils/psTrace.c	/^psBool psTraceSetLevel(const char *comp,   \/\/ component of interest$/;"	f
+psTraceSetLevel	src/sysUtils/psTrace.h	/^#        define psTraceSetLevel(/;"	d
+psTraceSetLevel	src/sysUtils/psTrace.h	/^psBool psTraceSetLevel(const char *facil,     \/\/\/< facilty of interest$/;"	p
+psType	include/psType.h	/^psType;$/;"	t
+psType	src/sysUtils/psType.h	/^psType;$/;"	t
+psU16	include/psType.h	/^typedef uint16_t psU16;                \/\/\/< 16-bit unsigned int$/;"	t
+psU16	src/sysUtils/psType.h	/^typedef uint16_t psU16;                \/\/\/< 16-bit unsigned int$/;"	t
+psU32	include/psType.h	/^typedef uint32_t psU32;                \/\/\/< 32-bit unsigned int$/;"	t
+psU32	src/sysUtils/psType.h	/^typedef uint32_t psU32;                \/\/\/< 32-bit unsigned int$/;"	t
+psU64	include/psType.h	/^typedef uint64_t psU64;                \/\/\/< 64-bit unsigned int$/;"	t
+psU64	src/sysUtils/psType.h	/^typedef uint64_t psU64;                \/\/\/< 64-bit unsigned int$/;"	t
+psU8	include/psType.h	/^typedef uint8_t psU8;                  \/\/\/< 8-bit unsigned int$/;"	t
+psU8	src/sysUtils/psType.h	/^typedef uint8_t psU8;                  \/\/\/< 8-bit unsigned int$/;"	t
+psUnaryOp	include/psMatrixVectorArithmetic.h	/^psType* psUnaryOp($/;"	p
+psUnaryOp	src/dataManip/psMatrixVectorArithmetic.c	/^psPtr psUnaryOp(psPtr out, psPtr in, char *op)$/;"	f
+psUnaryOp	src/dataManip/psMatrixVectorArithmetic.h	/^psType* psUnaryOp($/;"	p
+psUnaryOp_EXIT	src/dataManip/psMatrixVectorArithmetic.c	/^    #define psUnaryOp_EXIT /;"	d	file:
+psVector	include/psVector.h	/^psVector;$/;"	t
+psVector	src/collections/psVector.h	/^psVector;$/;"	t
+psVectorAlloc	include/psVector.h	/^psVector* psVectorAlloc($/;"	p
+psVectorAlloc	src/collections/psVector.c	/^psVector* psVectorAlloc(psU32 nalloc, psElemType elemType)$/;"	f
+psVectorAlloc	src/collections/psVector.h	/^psVector* psVectorAlloc($/;"	p
+psVectorComplex	include/psVectorFFT.h	/^psVector* psVectorComplex($/;"	p
+psVectorComplex	src/dataManip/psVectorFFT.c	/^psVector* psVectorComplex(psVector* out, const psVector* real, const psVector* imag)$/;"	f
+psVectorComplex	src/dataManip/psVectorFFT.h	/^psVector* psVectorComplex($/;"	p
+psVectorConjugate	include/psVectorFFT.h	/^psVector* psVectorConjugate($/;"	p
+psVectorConjugate	src/dataManip/psVectorFFT.c	/^psVector* psVectorConjugate(psVector* out, const psVector* in)$/;"	f
+psVectorConjugate	src/dataManip/psVectorFFT.h	/^psVector* psVectorConjugate($/;"	p
+psVectorCopy	include/psVector.h	/^psVector* psVectorCopy($/;"	p
+psVectorCopy	src/collections/psVector.c	/^psVector* psVectorCopy(psVector* out, const psVector* in, psElemType type)$/;"	f
+psVectorCopy	src/collections/psVector.h	/^psVector* psVectorCopy($/;"	p
+psVectorFFT	include/psVectorFFT.h	/^psVector* psVectorFFT($/;"	p
+psVectorFFT	src/dataManip/psVectorFFT.c	/^psVector* psVectorFFT(psVector* out, const psVector* in, psFFTFlags direction)$/;"	f
+psVectorFFT	src/dataManip/psVectorFFT.h	/^psVector* psVectorFFT($/;"	p
+psVectorFitPolynomial1D	include/psMinimize.h	/^psPolynomial1D* psVectorFitPolynomial1D($/;"	p
+psVectorFitPolynomial1D	src/dataManip/psMinimize.c	/^psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly,$/;"	f
+psVectorFitPolynomial1D	src/dataManip/psMinimize.h	/^psPolynomial1D* psVectorFitPolynomial1D($/;"	p
+psVectorFitSpline1D	include/psMinimize.h	/^psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              \/\/\/< The spline which will be generated.$/;"	p
+psVectorFitSpline1D	src/dataManip/psMinimize.c	/^psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              \/\/\/< The spline which will be generated.$/;"	f
+psVectorFitSpline1D	src/dataManip/psMinimize.h	/^psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              \/\/\/< The spline which will be generated.$/;"	p
+psVectorHistogram	include/psStats.h	/^psHistogram* psVectorHistogram($/;"	p
+psVectorHistogram	src/dataManip/psStats.c	/^psHistogram* psVectorHistogram(psHistogram* out,$/;"	f
+psVectorHistogram	src/dataManip/psStats.h	/^psHistogram* psVectorHistogram($/;"	p
+psVectorImaginary	include/psVectorFFT.h	/^psVector* psVectorImaginary($/;"	p
+psVectorImaginary	src/dataManip/psVectorFFT.c	/^psVector* psVectorImaginary(psVector* out, const psVector* in)$/;"	f
+psVectorImaginary	src/dataManip/psVectorFFT.h	/^psVector* psVectorImaginary($/;"	p
+psVectorPowerSpectrum	include/psVectorFFT.h	/^psVector* psVectorPowerSpectrum($/;"	p
+psVectorPowerSpectrum	src/dataManip/psVectorFFT.c	/^psVector* psVectorPowerSpectrum(psVector* out, const psVector* in)$/;"	f
+psVectorPowerSpectrum	src/dataManip/psVectorFFT.h	/^psVector* psVectorPowerSpectrum($/;"	p
+psVectorReal	include/psVectorFFT.h	/^psVector* psVectorReal($/;"	p
+psVectorReal	src/dataManip/psVectorFFT.c	/^psVector* psVectorReal(psVector* out, const psVector* in)$/;"	f
+psVectorReal	src/dataManip/psVectorFFT.h	/^psVector* psVectorReal($/;"	p
+psVectorRealloc	include/psVector.h	/^psVector* psVectorRealloc($/;"	p
+psVectorRealloc	src/collections/psVector.c	/^psVector* psVectorRealloc(psVector* restrict in, psU32 nalloc)$/;"	f
+psVectorRealloc	src/collections/psVector.h	/^psVector* psVectorRealloc($/;"	p
+psVectorRecycle	include/psVector.h	/^psVector* psVectorRecycle($/;"	p
+psVectorRecycle	src/collections/psVector.c	/^psVector* psVectorRecycle(psVector* restrict in, psU32 n, psElemType type)$/;"	f
+psVectorRecycle	src/collections/psVector.h	/^psVector* psVectorRecycle($/;"	p
+psVectorSort	include/psVector.h	/^psVector* psVectorSort($/;"	p
+psVectorSort	src/collections/psVector.c	/^psVector* psVectorSort(psVector* restrict outVector, const psVector* restrict inVector)$/;"	f
+psVectorSort	src/collections/psVector.h	/^psVector* psVectorSort($/;"	p
+psVectorSortIndex	include/psVector.h	/^psVector* psVectorSortIndex($/;"	p
+psVectorSortIndex	src/collections/psVector.c	/^psVector* psVectorSortIndex(psVector* restrict outVector, const psVector* restrict inVector)$/;"	f
+psVectorSortIndex	src/collections/psVector.h	/^psVector* psVectorSortIndex($/;"	p
+psVectorStats	include/psStats.h	/^psStats* psVectorStats($/;"	p
+psVectorStats	src/dataManip/psStats.c	/^psStats* psVectorStats(psStats* stats,$/;"	f
+psVectorStats	src/dataManip/psStats.h	/^psStats* psVectorStats($/;"	p
+psVectorToGslVector	src/dataManip/psMatrix.c	/^static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector)$/;"	f	file:
+psVectorToGslVector	src/dataManip/psMatrix.c	/^static void  psVectorToGslVector(gsl_vector *outGslVector, const psVector *inVector);$/;"	p	file:
+psVectorToMatrix	include/psMatrix.h	/^psImage* psVectorToMatrix($/;"	p
+psVectorToMatrix	src/dataManip/psMatrix.c	/^psImage* psVectorToMatrix(psImage* outImage, const psVector* inVector)$/;"	f
+psVectorToMatrix	src/dataManip/psMatrix.h	/^psImage* psVectorToMatrix($/;"	p
+psWarning	include/psLogMsg.h	/^void psWarning($/;"	p
+psWarning	src/sysUtils/psLogMsg.c	/^void psWarning(const char* name, const char* fmt, ...)$/;"	f
+psWarning	src/sysUtils/psLogMsg.h	/^void psWarning($/;"	p
+pushErrorStack	src/sysUtils/psError.c	/^static void pushErrorStack(psErr* err)$/;"	f	file:
+pushErrorStack	src/sysUtils/psError.c	/^static void pushErrorStack(psErr* err);$/;"	p	file:
+r	include/psCoord.h	/^    double r;                   \/\/\/< RA$/;"	m	struct:psSphere
+r	src/astronomy/psCoord.h	/^    double r;                   \/\/\/< RA$/;"	m	struct:psSphere
+rErr	include/psCoord.h	/^    double rErr;                \/\/\/< Error in RA$/;"	m	struct:psSphere
+rErr	src/astronomy/psCoord.h	/^    double rErr;                \/\/\/< Error in RA$/;"	m	struct:psSphere
+ra	include/psAstrometry.h	/^    const double ra;                   \/\/\/< Telescope boresight, right ascention$/;"	m	struct:psExposure
+ra	src/astronomy/psAstrometry.h	/^    const double ra;                   \/\/\/< Telescope boresight, right ascention$/;"	m	struct:psExposure
+rawDataBuffer	include/psImage.h	/^    psPtr rawDataBuffer;$/;"	m	struct:psImage
+rawDataBuffer	src/image/psImage.h	/^    psPtr rawDataBuffer;$/;"	m	struct:psImage
+readoutFree	src/astronomy/psAstrometry.c	/^static void readoutFree(psReadout* readout)$/;"	f	file:
+readouts	include/psAstrometry.h	/^    psArray* readouts;                 \/\/\/< readouts from the cell$/;"	m
+readouts	src/astronomy/psAstrometry.h	/^    psArray* readouts;                 \/\/\/< readouts from the cell$/;"	m
+realloc	include/psMemory.h	/^#define realloc(/;"	d
+realloc	src/sysUtils/psMemory.h	/^#define realloc(/;"	d
+recycleBinSize	src/sysUtils/psMemory.c	/^static psS32 recycleBinSize[14] = {$/;"	v	file:
+recycleBins	src/sysUtils/psMemory.c	/^static psS32 recycleBins = 13;$/;"	v	file:
+recycleMemBlockList	src/sysUtils/psMemory.c	/^static psMemBlock* recycleMemBlockList[13] = {$/;"	v	file:
+recycleMemBlockListMutex	src/sysUtils/psMemory.c	/^static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER;$/;"	v	file:
+refCounter	include/psMemory.h	/^    psReferenceCount refCounter;       \/\/\/< how many times pointer is referenced$/;"	m	struct:psMemBlock
+refCounter	src/sysUtils/psMemory.h	/^    psReferenceCount refCounter;       \/\/\/< how many times pointer is referenced$/;"	m	struct:psMemBlock
+refCounterMutex	include/psMemory.h	/^    pthread_mutex_t refCounterMutex;   \/\/\/< mutex to ensure exclusive access to reference counter$/;"	m	struct:psMemBlock
+refCounterMutex	src/sysUtils/psMemory.h	/^    pthread_mutex_t refCounterMutex;   \/\/\/< mutex to ensure exclusive access to reference counter$/;"	m	struct:psMemBlock
+refractA	include/psAstrometry.h	/^    const double refractA;             \/\/\/< refraction constant A (radians)$/;"	m
+refractA	src/astronomy/psAstrometry.h	/^    const double refractA;             \/\/\/< refraction constant A (radians)$/;"	m
+refractB	include/psAstrometry.h	/^    const double refractB;             \/\/\/< refraction constant B (radians)$/;"	m
+refractB	src/astronomy/psAstrometry.h	/^    const double refractB;             \/\/\/< refraction constant B (radians)$/;"	m
+repeatedChars	src/astronomy/psMetadataIO.c	/^psS32 repeatedChars(char *inString, char ch)$/;"	f
+rmsX	include/psAstrometry.h	/^    float rmsX;                        \/\/\/< RMS for x transformation fits$/;"	m	struct:psFPA
+rmsX	src/astronomy/psAstrometry.h	/^    float rmsX;                        \/\/\/< RMS for x transformation fits$/;"	m	struct:psFPA
+rmsY	include/psAstrometry.h	/^    float rmsY;                        \/\/\/< RMS for y transformation fits$/;"	m	struct:psFPA
+rmsY	src/astronomy/psAstrometry.h	/^    float rmsY;                        \/\/\/< RMS for y transformation fits$/;"	m	struct:psFPA
+robustLQ	include/psStats.h	/^    psF64 robustLQ;            \/\/\/< robust lower quartile$/;"	m
+robustLQ	src/dataManip/psStats.h	/^    psF64 robustLQ;            \/\/\/< robust lower quartile$/;"	m
+robustMean	include/psStats.h	/^    psF64 robustMean;          \/\/\/< robust mean of array$/;"	m
+robustMean	src/dataManip/psStats.h	/^    psF64 robustMean;          \/\/\/< robust mean of array$/;"	m
+robustMedian	include/psStats.h	/^    psF64 robustMedian;        \/\/\/< robust median of array$/;"	m
+robustMedian	src/dataManip/psStats.h	/^    psF64 robustMedian;        \/\/\/< robust median of array$/;"	m
+robustMode	include/psStats.h	/^    psF64 robustMode;          \/\/\/< Robust mode of array$/;"	m
+robustMode	src/dataManip/psStats.h	/^    psF64 robustMode;          \/\/\/< Robust mode of array$/;"	m
+robustN50	include/psStats.h	/^    psS32 robustN50;              \/\/\/<$/;"	m
+robustN50	src/dataManip/psStats.h	/^    psS32 robustN50;              \/\/\/<$/;"	m
+robustNfit	include/psStats.h	/^    psS32 robustNfit;             \/\/\/<$/;"	m
+robustNfit	src/dataManip/psStats.h	/^    psS32 robustNfit;             \/\/\/<$/;"	m
+robustStdev	include/psStats.h	/^    psF64 robustStdev;         \/\/\/< robust standard deviation of array$/;"	m
+robustStdev	src/dataManip/psStats.h	/^    psF64 robustStdev;         \/\/\/< robust standard deviation of array$/;"	m
+robustUQ	include/psStats.h	/^    psF64 robustUQ;            \/\/\/< robust upper quartile$/;"	m
+robustUQ	src/dataManip/psStats.h	/^    psF64 robustUQ;            \/\/\/< robust upper quartile$/;"	m
+rotAngle	include/psAstrometry.h	/^    const float rotAngle;              \/\/\/< Rotator position angle in degrees? XXX: see bug#209$/;"	m	struct:psExposure
+rotAngle	src/astronomy/psAstrometry.h	/^    const float rotAngle;              \/\/\/< Rotator position angle in degrees? XXX: see bug#209$/;"	m	struct:psExposure
+row0	include/psAstrometry.h	/^    const psS32 row0;                    \/\/\/< Offset from the bottom of chip.$/;"	m
+row0	include/psImage.h	/^    const psS32 row0;                    \/\/\/< Row position relative to parent.$/;"	m	struct:psImage
+row0	src/astronomy/psAstrometry.h	/^    const psS32 row0;                    \/\/\/< Offset from the bottom of chip.$/;"	m
+row0	src/image/psImage.h	/^    const psS32 row0;                    \/\/\/< Row position relative to parent.$/;"	m	struct:psImage
+rowBins	include/psAstrometry.h	/^    const psU32 rowBins;        \/\/\/< Amount of binning in y-dimension$/;"	m
+rowBins	src/astronomy/psAstrometry.h	/^    const psU32 rowBins;        \/\/\/< Amount of binning in y-dimension$/;"	m
+run	docs/html/index.html	/^<\/pre> <em>This builds and installs files to psLib\/lib and psLib\/include.<\/em><h2><a class="anchor" name="run">$/;"	a
+runTest	include/psTest.h	/^#define runTest(/;"	d
+runTest	test/psTest.h	/^#define runTest(/;"	d
+runTestSuite	include/psTest.h	/^#define runTestSuite(/;"	d
+runTestSuite	test/psTest.h	/^#define runTestSuite(/;"	d
+sA	include/psPhotometry.h	/^    float sA;                   \/\/\/< Color offset for references$/;"	m
+sA	src/astronomy/psPhotometry.h	/^    float sA;                   \/\/\/< Color offset for references$/;"	m
+sM	include/psPhotometry.h	/^    psPhotSystem sM;            \/\/\/< Secondary color reference$/;"	m
+sM	src/astronomy/psPhotometry.h	/^    psPhotSystem sM;            \/\/\/< Secondary color reference$/;"	m
+sP	include/psPhotometry.h	/^    psPhotSystem sP;            \/\/\/< Secondary color reference$/;"	m
+sP	src/astronomy/psPhotometry.h	/^    psPhotSystem sP;            \/\/\/< Secondary color reference$/;"	m
+sampleLQ	include/psStats.h	/^    psF64 sampleLQ;            \/\/\/< lower quartile of sample$/;"	m
+sampleLQ	src/dataManip/psStats.h	/^    psF64 sampleLQ;            \/\/\/< lower quartile of sample$/;"	m
+sampleMean	include/psStats.h	/^    psF64 sampleMean;          \/\/\/< formal mean of sample$/;"	m
+sampleMean	src/dataManip/psStats.h	/^    psF64 sampleMean;          \/\/\/< formal mean of sample$/;"	m
+sampleMedian	include/psStats.h	/^    psF64 sampleMedian;        \/\/\/< formal median of sample$/;"	m
+sampleMedian	src/dataManip/psStats.h	/^    psF64 sampleMedian;        \/\/\/< formal median of sample$/;"	m
+sampleStdev	include/psStats.h	/^    psF64 sampleStdev;         \/\/\/< standard deviation of sample$/;"	m
+sampleStdev	src/dataManip/psStats.h	/^    psF64 sampleStdev;         \/\/\/< standard deviation of sample$/;"	m
+sampleUQ	include/psStats.h	/^    psF64 sampleUQ;            \/\/\/< upper quartile of sample$/;"	m
+sampleUQ	src/dataManip/psStats.h	/^    psF64 sampleUQ;            \/\/\/< upper quartile of sample$/;"	m
+searchTables	src/astronomy/psTime.c	/^psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables)$/;"	f
+searchTables	src/astronomy/psTime.c	/^psF64 searchTables(psF64 index, psU64 column, psLookupStatusType *status, char *metadataTableNames[], psU32 nTables);$/;"	p	file:
+sec	include/psTime.h	/^    psS64 sec;          \/\/\/< Seconds since epoch, Jan 1, 1970.$/;"	m	struct:psTime
+sec	src/astronomy/psTime.h	/^    psS64 sec;          \/\/\/< Seconds since epoch, Jan 1, 1970.$/;"	m	struct:psTime
+setData	test/dataManip/tst_psMinimize04.c	/^double setData(double x)$/;"	f
+setData	test/dataManip/tst_psMinimize04_F32.c	/^float setData(float x)$/;"	f
+setData	test/dataManip/tst_psMinimize04b.c	/^double setData(double x)$/;"	f
+setData	test/dataManip/tst_psMinimize04b_F32.c	/^float setData(float x)$/;"	f
+siderealTime	include/psAstrometry.h	/^    const double siderealTime;         \/\/\/< local apparent sidereal time (radians)$/;"	m
+siderealTime	src/astronomy/psAstrometry.h	/^    const double siderealTime;         \/\/\/< local apparent sidereal time (radians)$/;"	m
+sinDeltaP	include/psCoord.h	/^    double sinDeltaP;                 \/\/\/< Sine of target pole latitude in the source system$/;"	m
+sinDeltaP	src/astronomy/psCoord.h	/^    double sinDeltaP;                 \/\/\/< Sine of target pole latitude in the source system$/;"	m
+sinLat	include/psAstrometry.h	/^    const double sinLat;               \/\/\/< sine of geodetic latitude$/;"	m
+sinLat	src/astronomy/psAstrometry.h	/^    const double sinLat;               \/\/\/< sine of geodetic latitude$/;"	m
+size	include/psList.h	/^    psU32 size;                        \/\/\/< number of elements on list$/;"	m
+size	src/collections/psList.h	/^    psU32 size;                        \/\/\/< number of elements on list$/;"	m
+slaAirmas	include/slalib.h	/^#define slaAirmas(/;"	d
+slaAirmas	src/astronomy/slalib.h	/^#define slaAirmas(/;"	d
+slaAoppa	include/slalib.h	/^#define slaAoppa(/;"	d
+slaAoppa	src/astronomy/slalib.h	/^#define slaAoppa(/;"	d
+slaAopqk	include/slalib.h	/^#define slaAopqk(/;"	d
+slaAopqk	src/astronomy/slalib.h	/^#define slaAopqk(/;"	d
+slaOapqk	include/slalib.h	/^#define slaOapqk(/;"	d
+slaOapqk	src/astronomy/slalib.h	/^#define slaOapqk(/;"	d
+spline	include/psFunctions.h	/^    psPolynomial1D **spline;      \/\/\/< An array of n pointers to the spline polynomials$/;"	m
+spline	src/dataManip/psFunctions.h	/^    psPolynomial1D **spline;      \/\/\/< An array of n pointers to the spline polynomials$/;"	m
+spline1DFree	src/dataManip/psFunctions.c	/^static void spline1DFree(psSpline1D *tmpSpline)$/;"	f	file:
+spline1DFree	src/dataManip/psFunctions.c	/^static void spline1DFree(psSpline1D *tmpSpline);$/;"	p	file:
+src	include/psPhotometry.h	/^    psPhotSystem src;           \/\/\/< Source photometric system$/;"	m
+src	src/astronomy/psPhotometry.h	/^    psPhotSystem src;           \/\/\/< Source photometric system$/;"	m
+startblock	include/psMemory.h	/^    const psPtr startblock;            \/\/\/< initialised to p_psMEMMAGIC$/;"	m	struct:psMemBlock
+startblock	src/sysUtils/psMemory.h	/^    const psPtr startblock;            \/\/\/< initialised to p_psMEMMAGIC$/;"	m	struct:psMemBlock
+staticErrorCodes	src/sysUtils/psErrorCodes.c	/^static psErrorDescription staticErrorCodes[] = {$/;"	v	file:
+subcomp	include/psTrace.h	/^        struct p_psComponent* *subcomp;     \/\/ next level of subcomponents$/;"	m	struct:p_psComponent
+subcomp	src/sysUtils/psTrace.h	/^        struct p_psComponent* *subcomp;     \/\/ next level of subcomponents$/;"	m	struct:p_psComponent
+t00	test/dataManip/tst_psFunc04.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psFunc07.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize04.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize04_F32.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize04b.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize04b_F32.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize05.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psMinimize07.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psRandom.c	/^psS32 t00()$/;"	f
+t00	test/dataManip/tst_psStats07.c	/^psS32 t00()$/;"	f
+t01	test/dataManip/tst_psFunc00.c	/^int t01()$/;"	f
+t01	test/dataManip/tst_psFunc04.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psFunc07.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize04.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize04_F32.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize04b.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize04b_F32.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize05.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize06.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psMinimize07.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psRandom.c	/^psS32 t01()$/;"	f
+t01	test/dataManip/tst_psStats07.c	/^psS32 t01()$/;"	f
+t02	test/dataManip/tst_psMinimize04.c	/^psS32 t02()$/;"	f
+t02	test/dataManip/tst_psMinimize04_F32.c	/^psS32 t02()$/;"	f
+t02	test/dataManip/tst_psMinimize04b.c	/^psS32 t02()$/;"	f
+t02	test/dataManip/tst_psMinimize04b_F32.c	/^psS32 t02()$/;"	f
+t02	test/dataManip/tst_psMinimize05.c	/^psS32 t02()$/;"	f
+t02	test/dataManip/tst_psRandom.c	/^psS32 t02()$/;"	f
+t03	test/dataManip/tst_psMinimize04.c	/^psS32 t03()$/;"	f
+t03	test/dataManip/tst_psMinimize04_F32.c	/^psS32 t03()$/;"	f
+t03	test/dataManip/tst_psMinimize04b.c	/^psS32 t03()$/;"	f
+t03	test/dataManip/tst_psMinimize04b_F32.c	/^psS32 t03()$/;"	f
+t03	test/dataManip/tst_psRandom.c	/^psS32 t03()$/;"	f
+t04	test/dataManip/tst_psRandom.c	/^psS32 t04()$/;"	f
+t05	test/dataManip/tst_psRandom.c	/^psS32 t05()$/;"	f
+t06	test/dataManip/tst_psRandom.c	/^psS32 t06()$/;"	f
+table	include/psMetadata.h	/^    psHash*  table;                    \/\/\/< Metadata in a hash table$/;"	m	struct:psMetadata
+table	src/astronomy/psMetadata.h	/^    psHash*  table;                    \/\/\/< Metadata in a hash table$/;"	m	struct:psMetadata
+tail	include/psList.h	/^    psListElem* tail;                  \/\/\/< last element on list (may be NULL)$/;"	m
+tail	src/collections/psList.h	/^    psListElem* tail;                  \/\/\/< last element on list (may be NULL)$/;"	m
+telescopeName	include/psAstrometry.h	/^    const char* telescopeName;         \/\/\/< name of telescope which provided exposure$/;"	m	struct:psExposure
+telescopeName	src/astronomy/psAstrometry.h	/^    const char* telescopeName;         \/\/\/< name of telescope which provided exposure$/;"	m	struct:psExposure
+temperature	include/psAstrometry.h	/^    const double temperature;          \/\/\/< ambient temperature (TDK)$/;"	m
+temperature	include/psAstrometry.h	/^    const float temperature;           \/\/\/< Air temperature in Kelvin$/;"	m	struct:psExposure
+temperature	src/astronomy/psAstrometry.h	/^    const double temperature;          \/\/\/< ambient temperature (TDK)$/;"	m
+temperature	src/astronomy/psAstrometry.h	/^    const float temperature;           \/\/\/< Air temperature in Kelvin$/;"	m	struct:psExposure
+test1	test/astronomy/tst_psAstrometry01.c	/^psS32 test1( void )$/;"	f
+test1	test/astronomy/tst_psAstrometry01.c	/^static psS32 test1( void );$/;"	p	file:
+test1	test/astronomy/tst_psCoord.c	/^psS32 test1( void )$/;"	f
+test1	test/astronomy/tst_psCoord.c	/^static psS32 test1( void );$/;"	p	file:
+test1	test/tst_template.c	/^psS32 test1( void )$/;"	f
+test1	test/tst_template.c	/^static psS32 test1( void );$/;"	p	file:
+test1b	test/astronomy/tst_psCoord.c	/^psS32 test1b( void )$/;"	f
+test1b	test/astronomy/tst_psCoord.c	/^static psS32 test1b( void );$/;"	p	file:
+test1c	test/astronomy/tst_psCoord.c	/^psS32 test1c( void )$/;"	f
+test1c	test/astronomy/tst_psCoord.c	/^static psS32 test1c( void );$/;"	p	file:
+test2	test/astronomy/tst_psAstrometry01.c	/^psS32 test2()$/;"	f
+test2	test/astronomy/tst_psAstrometry01.c	/^static psS32 test2( void );$/;"	p	file:
+test2	test/astronomy/tst_psCoord.c	/^psS32 test2( void )$/;"	f
+test2	test/astronomy/tst_psCoord.c	/^static psS32 test2( void );$/;"	p	file:
+test2	test/tst_template.c	/^psS32 test2( void )$/;"	f
+test2	test/tst_template.c	/^static psS32 test2( void );$/;"	p	file:
+test20	test/astronomy/tst_psCoord.c	/^psS32 test20( void )$/;"	f
+test20	test/astronomy/tst_psCoord.c	/^static psS32 test20( void );$/;"	p	file:
+test21	test/astronomy/tst_psCoord.c	/^psS32 test21( void )$/;"	f
+test21	test/astronomy/tst_psCoord.c	/^static psS32 test21( void );$/;"	p	file:
+test3	test/astronomy/tst_psAstrometry01.c	/^psS32 test3( void )$/;"	f
+test3	test/astronomy/tst_psAstrometry01.c	/^static psS32 test3( void );$/;"	p	file:
+test3	test/astronomy/tst_psCoord.c	/^psS32 test3( void )$/;"	f
+test3	test/astronomy/tst_psCoord.c	/^static psS32 test3( void );$/;"	p	file:
+test3	test/tst_template.c	/^psS32 test3( void )$/;"	f
+test3	test/tst_template.c	/^static psS32 test3( void );$/;"	p	file:
+test4	test/astronomy/tst_psCoord.c	/^psS32 test4( void )$/;"	f
+test4	test/astronomy/tst_psCoord.c	/^static psS32 test4( void );$/;"	p	file:
+test40	test/astronomy/tst_psCoord.c	/^psS32 test40( void )$/;"	f
+test40	test/astronomy/tst_psCoord.c	/^static psS32 test40( void );$/;"	p	file:
+test41	test/astronomy/tst_psCoord.c	/^psS32 test41( void )$/;"	f
+test41	test/astronomy/tst_psCoord.c	/^static psS32 test41( void );$/;"	p	file:
+test5	test/astronomy/tst_psCoord.c	/^psS32 test5( void )$/;"	f
+test5	test/astronomy/tst_psCoord.c	/^static psS32 test5( void );$/;"	p	file:
+test6	test/astronomy/tst_psCoord.c	/^psS32 test6( void )$/;"	f
+test6	test/astronomy/tst_psCoord.c	/^static psS32 test6( void );$/;"	p	file:
+test7	test/astronomy/tst_psCoord.c	/^psS32 test7( void )$/;"	f
+test7	test/astronomy/tst_psCoord.c	/^static psS32 test7( void );$/;"	p	file:
+test8	test/astronomy/tst_psCoord.c	/^psS32 test8( void )$/;"	f
+test8	test/astronomy/tst_psCoord.c	/^static psS32 test8( void );$/;"	p	file:
+testAbort00	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort00(void)$/;"	f	file:
+testAbort00	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort00(void);$/;"	p	file:
+testAbort01	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort01(void)$/;"	f	file:
+testAbort01	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort01(void);$/;"	p	file:
+testAbort02	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort02(void)$/;"	f	file:
+testAbort02	test/sysUtils/tst_psAbort.c	/^static psS32 testAbort02(void);$/;"	p	file:
+testArrayAdd	test/collections/tst_psArray02.c	/^psS32 testArrayAdd( void )$/;"	f
+testArrayAdd	test/collections/tst_psArray02.c	/^static psS32 testArrayAdd( void );$/;"	p	file:
+testBinOpScalarBoth	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^psS32 testBinOpScalarBoth(void)$/;"	f
+testBinOpScalarBoth	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^static psS32 testBinOpScalarBoth(void);$/;"	p	file:
+testBinOpScalarFirst	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^psS32 testBinOpScalarFirst(void)$/;"	f
+testBinOpScalarFirst	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^static psS32 testBinOpScalarFirst(void);$/;"	p	file:
+testBinOpScalarSecond	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^psS32 testBinOpScalarSecond(void)$/;"	f
+testBinOpScalarSecond	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^static psS32 testBinOpScalarSecond(void);$/;"	p	file:
+testBinaryOpMM	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^    #define testBinaryOpMM(/;"	d	file:
+testBinaryOpMS	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^    #define testBinaryOpMS(/;"	d	file:
+testBinaryOpMV	test/dataManip/tst_psMatrixVectorArithmetic01.c	/^    #define testBinaryOpMV(/;"	d	file:
+testBitSet01a	test/collections/tst_psBitSet.c	/^psS32 testBitSet01a(void)$/;"	f
+testBitSet01a	test/collections/tst_psBitSet.c	/^static psS32 testBitSet01a(void);$/;"	p	file:
+testBitSet01b	test/collections/tst_psBitSet.c	/^psS32 testBitSet01b(void)$/;"	f
+testBitSet01b	test/collections/tst_psBitSet.c	/^static psS32 testBitSet01b(void);$/;"	p	file:
+testBitSet01c	test/collections/tst_psBitSet.c	/^static psS32 testBitSet01c(void)$/;"	f	file:
+testBitSet01c	test/collections/tst_psBitSet.c	/^static psS32 testBitSet01c(void);$/;"	p	file:
+testBitSet02	test/collections/tst_psBitSet.c	/^psS32 testBitSet02()$/;"	f
+testBitSet02	test/collections/tst_psBitSet.c	/^static psS32 testBitSet02(void);$/;"	p	file:
+testBitSet03	test/collections/tst_psBitSet.c	/^static psS32 testBitSet03(void)$/;"	f	file:
+testBitSet03	test/collections/tst_psBitSet.c	/^static psS32 testBitSet03(void);$/;"	p	file:
+testBitSet04	test/collections/tst_psBitSet.c	/^static psS32 testBitSet04(void)$/;"	f	file:
+testBitSet04	test/collections/tst_psBitSet.c	/^static psS32 testBitSet04(void);$/;"	p	file:
+testBitSet05	test/collections/tst_psBitSet.c	/^static psS32 testBitSet05(void)$/;"	f	file:
+testBitSet05	test/collections/tst_psBitSet.c	/^static psS32 testBitSet05(void);$/;"	p	file:
+testBitSet06	test/collections/tst_psBitSet.c	/^static psS32 testBitSet06(void)$/;"	f	file:
+testBitSet06	test/collections/tst_psBitSet.c	/^static psS32 testBitSet06(void);$/;"	p	file:
+testCellAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testCellAlloc(void)$/;"	f	file:
+testCellAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testCellAlloc(void);$/;"	p	file:
+testChipAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testChipAlloc(void)$/;"	f	file:
+testChipAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testChipAlloc(void);$/;"	p	file:
+testDescription	include/psTest.h	/^testDescription;$/;"	t
+testDescription	test/psTest.h	/^testDescription;$/;"	t
+testError00	test/sysUtils/tst_psError.c	/^static psS32 testError00(void)$/;"	f	file:
+testError00	test/sysUtils/tst_psError.c	/^static psS32 testError00(void);$/;"	p	file:
+testError01	test/sysUtils/tst_psError.c	/^static psS32 testError01(void)$/;"	f	file:
+testError01	test/sysUtils/tst_psError.c	/^static psS32 testError01(void);$/;"	p	file:
+testError02	test/sysUtils/tst_psError.c	/^static psS32 testError02(void)$/;"	f	file:
+testError02	test/sysUtils/tst_psError.c	/^static psS32 testError02(void);$/;"	p	file:
+testError03	test/sysUtils/tst_psError.c	/^static psS32 testError03(void)$/;"	f	file:
+testError03	test/sysUtils/tst_psError.c	/^static psS32 testError03(void);$/;"	p	file:
+testError04	test/sysUtils/tst_psError.c	/^static psS32 testError04(void)$/;"	f	file:
+testError04	test/sysUtils/tst_psError.c	/^static psS32 testError04(void);$/;"	p	file:
+testError05	test/sysUtils/tst_psError.c	/^static psS32 testError05(void)$/;"	f	file:
+testError05	test/sysUtils/tst_psError.c	/^static psS32 testError05(void);$/;"	p	file:
+testErrorRegister	test/sysUtils/tst_psError.c	/^static psS32 testErrorRegister(void)$/;"	f	file:
+testErrorRegister	test/sysUtils/tst_psError.c	/^static psS32 testErrorRegister(void);$/;"	p	file:
+testExposureAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testExposureAlloc(void)$/;"	f	file:
+testExposureAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testExposureAlloc(void);$/;"	p	file:
+testFPAAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testFPAAlloc(void)$/;"	f	file:
+testFPAAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testFPAAlloc(void);$/;"	p	file:
+testFcn	include/psTest.h	/^typedef psS32 (*testFcn)(void);$/;"	t
+testFcn	test/psTest.h	/^typedef psS32 (*testFcn)(void);$/;"	t
+testImageAlloc	test/image/tst_psImage.c	/^psS32 testImageAlloc(void)$/;"	f
+testImageAlloc	test/image/tst_psImage.c	/^static psS32 testImageAlloc(void);$/;"	p	file:
+testImageClip	test/image/tst_psImageManip.c	/^psS32 testImageClip(void)$/;"	f
+testImageClip	test/image/tst_psImageManip.c	/^static psS32 testImageClip(void);$/;"	p	file:
+testImageClipByComplexType	test/image/tst_psImageManip.c	/^    #define testImageClipByComplexType(/;"	d	file:
+testImageClipByType	test/image/tst_psImageManip.c	/^    #define testImageClipByType(/;"	d	file:
+testImageClipComplexByType	test/image/tst_psImageManip.c	/^    #define testImageClipComplexByType(/;"	d	file:
+testImageClipComplexRegion	test/image/tst_psImageManip.c	/^psS32 testImageClipComplexRegion(void)$/;"	f
+testImageClipComplexRegion	test/image/tst_psImageManip.c	/^static psS32 testImageClipComplexRegion(void);$/;"	p	file:
+testImageClipNAN	test/image/tst_psImageManip.c	/^psS32 testImageClipNAN(void)$/;"	f
+testImageClipNAN	test/image/tst_psImageManip.c	/^static psS32 testImageClipNAN(void);$/;"	p	file:
+testImageClipNaNByType	test/image/tst_psImageManip.c	/^    #define testImageClipNaNByType(/;"	d	file:
+testImageComplex	test/image/tst_psImageFFT.c	/^psS32 testImageComplex(void)$/;"	f
+testImageComplex	test/image/tst_psImageFFT.c	/^static psS32 testImageComplex(void);$/;"	p	file:
+testImageConjugate	test/image/tst_psImageFFT.c	/^psS32 testImageConjugate(void)$/;"	f
+testImageConjugate	test/image/tst_psImageFFT.c	/^static psS32 testImageConjugate(void);$/;"	p	file:
+testImageCopy	test/image/tst_psImage.c	/^psS32 testImageCopy(void)$/;"	f
+testImageCopy	test/image/tst_psImage.c	/^static psS32 testImageCopy(void);$/;"	p	file:
+testImageCopyType	test/image/tst_psImage.c	/^    #define testImageCopyType(/;"	d	file:
+testImageCopyTypes	test/image/tst_psImage.c	/^    #define testImageCopyTypes(/;"	d	file:
+testImageCut	test/image/tst_psImageExtraction.c	/^static psS32 testImageCut(void)$/;"	f	file:
+testImageCut	test/image/tst_psImageExtraction.c	/^static psS32 testImageCut(void);$/;"	p	file:
+testImageFFT	test/image/tst_psImageFFT.c	/^psS32 testImageFFT(void)$/;"	f
+testImageFFT	test/image/tst_psImageFFT.c	/^static psS32 testImageFFT(void);$/;"	p	file:
+testImageOverlay	test/image/tst_psImageManip.c	/^psS32 testImageOverlay(void)$/;"	f
+testImageOverlay	test/image/tst_psImageManip.c	/^static psS32 testImageOverlay(void);$/;"	p	file:
+testImagePowerSpectrum	test/image/tst_psImageFFT.c	/^psS32 testImagePowerSpectrum(void)$/;"	f
+testImagePowerSpectrum	test/image/tst_psImageFFT.c	/^static psS32 testImagePowerSpectrum(void);$/;"	p	file:
+testImageRadialCut	test/image/tst_psImageExtraction.c	/^static psS32 testImageRadialCut(void)$/;"	f	file:
+testImageRadialCut	test/image/tst_psImageExtraction.c	/^static psS32 testImageRadialCut(void);$/;"	p	file:
+testImageRead	test/image/tst_psImageIO.c	/^psS32 testImageRead(void)$/;"	f
+testImageRead	test/image/tst_psImageIO.c	/^static psS32 testImageRead(void);$/;"	p	file:
+testImageRealImaginary	test/image/tst_psImageFFT.c	/^psS32 testImageRealImaginary(void)$/;"	f
+testImageRealImaginary	test/image/tst_psImageFFT.c	/^static psS32 testImageRealImaginary(void);$/;"	p	file:
+testImageRebin	test/image/tst_psImageManip.c	/^static psS32 testImageRebin(void)$/;"	f	file:
+testImageRebin	test/image/tst_psImageManip.c	/^static psS32 testImageRebin(void);$/;"	p	file:
+testImageResample	test/image/tst_psImageManip.c	/^static psS32 testImageResample(void)$/;"	f	file:
+testImageResample	test/image/tst_psImageManip.c	/^static psS32 testImageResample(void);$/;"	p	file:
+testImageRoll	test/image/tst_psImageManip.c	/^static psS32 testImageRoll(void)$/;"	f	file:
+testImageRoll	test/image/tst_psImageManip.c	/^static psS32 testImageRoll(void);$/;"	p	file:
+testImageRotate	test/image/tst_psImageManip.c	/^psS32 testImageRotate(void)$/;"	f
+testImageRotate	test/image/tst_psImageManip.c	/^static psS32 testImageRotate(void);$/;"	p	file:
+testImageShift	test/image/tst_psImageManip.c	/^static psS32 testImageShift(void)$/;"	f	file:
+testImageShift	test/image/tst_psImageManip.c	/^static psS32 testImageShift(void);$/;"	p	file:
+testImageShiftCase	test/image/tst_psImageManip.c	/^static psS32 testImageShiftCase(psS32 cols, psS32 rows, float colShift,float rowShift);$/;"	p	file:
+testImageShiftCase	test/image/tst_psImageManip.c	/^static psS32 testImageShiftCase(psS32 cols,$/;"	f	file:
+testImageSlice	test/image/tst_psImageExtraction.c	/^psS32 testImageSlice(void)$/;"	f
+testImageSlice	test/image/tst_psImageExtraction.c	/^static psS32 testImageSlice(void);$/;"	p	file:
+testImageSubsection	test/image/tst_psImageExtraction.c	/^psS32 testImageSubsection(void)$/;"	f
+testImageSubsection	test/image/tst_psImageExtraction.c	/^static psS32 testImageSubsection(void);$/;"	p	file:
+testImageSubset	test/image/tst_psImageExtraction.c	/^psS32 testImageSubset(void)$/;"	f
+testImageSubset	test/image/tst_psImageExtraction.c	/^static psS32 testImageSubset(void);$/;"	p	file:
+testImageTrim	test/image/tst_psImageExtraction.c	/^static psS32 testImageTrim(void)$/;"	f	file:
+testImageTrim	test/image/tst_psImageExtraction.c	/^static psS32 testImageTrim(void);$/;"	p	file:
+testImageWrite	test/image/tst_psImageIO.c	/^psS32 testImageWrite(void)$/;"	f
+testImageWrite	test/image/tst_psImageIO.c	/^static psS32 testImageWrite(void);$/;"	p	file:
+testInterpolate1D	test/image/tst_psImageInterpolate.c	/^psS32 testInterpolate1D(void)$/;"	f
+testInterpolate1D	test/image/tst_psImageInterpolate.c	/^static psS32 testInterpolate1D(void);$/;"	p	file:
+testInterpolateError	test/image/tst_psImageInterpolate.c	/^psS32 testInterpolateError(void)$/;"	f
+testInterpolateError	test/image/tst_psImageInterpolate.c	/^static psS32 testInterpolateError(void);$/;"	p	file:
+testInterpolateFlatBilinear	test/image/tst_psImageInterpolate.c	/^psS32 testInterpolateFlatBilinear(void)$/;"	f
+testInterpolateFlatBilinear	test/image/tst_psImageInterpolate.c	/^static psS32 testInterpolateFlatBilinear(void);$/;"	p	file:
+testInterpolateMaskFlatBilinear	test/image/tst_psImageInterpolate.c	/^psS32 testInterpolateMaskFlatBilinear(void)$/;"	f
+testInterpolateMaskFlatBilinear	test/image/tst_psImageInterpolate.c	/^static psS32 testInterpolateMaskFlatBilinear(void);$/;"	p	file:
+testKernelAlloc	test/image/tst_psImageConvolve.c	/^static psS32 testKernelAlloc(void)$/;"	f	file:
+testKernelAlloc	test/image/tst_psImageConvolve.c	/^static psS32 testKernelAlloc(void);$/;"	p	file:
+testKernelGenerate	test/image/tst_psImageConvolve.c	/^static psS32 testKernelGenerate(void)$/;"	f	file:
+testKernelGenerate	test/image/tst_psImageConvolve.c	/^static psS32 testKernelGenerate(void);$/;"	p	file:
+testListAdd	test/collections/tst_psList.c	/^psS32 testListAdd(void)$/;"	f
+testListAdd	test/collections/tst_psList.c	/^static psS32 testListAdd(void);$/;"	p	file:
+testListAlloc	test/collections/tst_psList.c	/^psS32 testListAlloc(void)$/;"	f
+testListAlloc	test/collections/tst_psList.c	/^static psS32 testListAlloc(void);$/;"	p	file:
+testListConvert	test/collections/tst_psList.c	/^psS32 testListConvert(void)$/;"	f
+testListConvert	test/collections/tst_psList.c	/^static psS32 testListConvert(void);$/;"	p	file:
+testListFree	test/collections/tst_psList.c	/^psS32 testListFree(void)$/;"	f
+testListFree	test/collections/tst_psList.c	/^static psS32 testListFree(void);$/;"	p	file:
+testListGet	test/collections/tst_psList.c	/^psS32 testListGet(void)$/;"	f
+testListGet	test/collections/tst_psList.c	/^static psS32 testListGet(void);$/;"	p	file:
+testListIterator	test/collections/tst_psList.c	/^psS32 testListIterator(void)$/;"	f
+testListIterator	test/collections/tst_psList.c	/^static psS32 testListIterator(void);$/;"	p	file:
+testListRemove	test/collections/tst_psList.c	/^psS32 testListRemove(void)$/;"	f
+testListRemove	test/collections/tst_psList.c	/^static psS32 testListRemove(void);$/;"	p	file:
+testListSort	test/collections/tst_psList.c	/^psS32 testListSort(void)$/;"	f
+testListSort	test/collections/tst_psList.c	/^static psS32 testListSort(void);$/;"	p	file:
+testLogMsg00	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg00()$/;"	f	file:
+testLogMsg00	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg00();$/;"	p	file:
+testLogMsg01	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg01()$/;"	f	file:
+testLogMsg01	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg01();$/;"	p	file:
+testLogMsg02	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg02()$/;"	f	file:
+testLogMsg02	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg02();$/;"	p	file:
+testLogMsg03	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg03()$/;"	f	file:
+testLogMsg03	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg03();$/;"	p	file:
+testLogMsg04	test/sysUtils/tst_psLogMsg.c	/^psS32 testLogMsg04()$/;"	f
+testLogMsg04	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg04();$/;"	p	file:
+testLogMsg05	test/sysUtils/tst_psLogMsg.c	/^psS32 testLogMsg05()$/;"	f
+testLogMsg05	test/sysUtils/tst_psLogMsg.c	/^static psS32 testLogMsg05();$/;"	p	file:
+testObservatoryAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testObservatoryAlloc(void)$/;"	f	file:
+testObservatoryAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testObservatoryAlloc(void);$/;"	p	file:
+testOverlayType	test/image/tst_psImageManip.c	/^    #define testOverlayType(/;"	d	file:
+testOverlayTypeOP	test/image/tst_psImageManip.c	/^    #define testOverlayTypeOP(/;"	d	file:
+testPointName	include/psTest.h	/^    const char* testPointName;$/;"	m
+testPointName	test/psTest.h	/^    const char* testPointName;$/;"	m
+testPointNumber	include/psTest.h	/^    psS32       testPointNumber;$/;"	m
+testPointNumber	test/psTest.h	/^    psS32       testPointNumber;$/;"	m
+testReadType	test/image/tst_psImageIO.c	/^    #define testReadType(/;"	d	file:
+testReadTypeSize	test/image/tst_psImageIO.c	/^    #define testReadTypeSize(/;"	d	file:
+testReadoutAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testReadoutAlloc(void)$/;"	f	file:
+testReadoutAlloc	test/astronomy/tst_psAstrometry.c	/^static psS32 testReadoutAlloc(void);$/;"	p	file:
+testRebinType	test/image/tst_psImageManip.c	/^    #define testRebinType(/;"	d	file:
+testRollType	test/image/tst_psImageManip.c	/^    #define testRollType(/;"	d	file:
+testScalarAlloc	test/collections/tst_psScalar.c	/^psS32 testScalarAlloc(void)$/;"	f
+testScalarAlloc	test/collections/tst_psScalar.c	/^static psS32 testScalarAlloc(void);$/;"	p	file:
+testScalarCopy	test/collections/tst_psScalar.c	/^psS32 testScalarCopy(void)$/;"	f
+testScalarCopy	test/collections/tst_psScalar.c	/^static psS32 testScalarCopy(void);$/;"	p	file:
+testStatus	test/dataManip/tst_psMinimize05.c	/^psS32 testStatus = true;$/;"	v
+testStatus	test/dataManip/tst_psMinimize06.c	/^psS32 testStatus = true;$/;"	v
+testStatus	test/dataManip/tst_psMinimize07.c	/^psS32 testStatus = true;$/;"	v
+testStatus	test/dataManip/tst_psRandom.c	/^psS32 testStatus = true;$/;"	v
+testStringCopy00	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy00(void)$/;"	f	file:
+testStringCopy00	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy00(void);$/;"	p	file:
+testStringCopy01	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy01(void)$/;"	f	file:
+testStringCopy01	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy01(void);$/;"	p	file:
+testStringCopy02	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy02(void)$/;"	f	file:
+testStringCopy02	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy02(void);$/;"	p	file:
+testStringCopy03	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy03(void)$/;"	f	file:
+testStringCopy03	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy03(void);$/;"	p	file:
+testStringCopy04	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy04(void)$/;"	f	file:
+testStringCopy04	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy04(void);$/;"	p	file:
+testStringCopy05	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy05(void)$/;"	f	file:
+testStringCopy05	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy05(void);$/;"	p	file:
+testStringCopy06	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy06(void)$/;"	f	file:
+testStringCopy06	test/sysUtils/tst_psStringCopy.c	/^static psS32 testStringCopy06(void);$/;"	p	file:
+testStruct	test/collections/tst_psArray.c	/^testStruct;$/;"	t	file:
+testStruct	test/collections/tst_psArray01.c	/^testStruct;$/;"	t	file:
+testStructCompare	test/collections/tst_psArray01.c	/^int testStructCompare(const void **a, const void **b)$/;"	f
+testTrace00	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace00(void)$/;"	f	file:
+testTrace00	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace00(void);$/;"	p	file:
+testTrace01	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace01(void)$/;"	f	file:
+testTrace01	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace01(void);$/;"	p	file:
+testTrace02	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace02(void)$/;"	f	file:
+testTrace02	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace02(void);$/;"	p	file:
+testTrace03	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace03(void)$/;"	f	file:
+testTrace03	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace03(void);$/;"	p	file:
+testTrace04	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace04(void)$/;"	f	file:
+testTrace04	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace04(void);$/;"	p	file:
+testTrace05	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace05(void)$/;"	f	file:
+testTrace05	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace05(void);$/;"	p	file:
+testTrace05a	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace05a(void)$/;"	f	file:
+testTrace05a	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace05a(void);$/;"	p	file:
+testTrace06	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace06(void)$/;"	f	file:
+testTrace06	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace06(void);$/;"	p	file:
+testTrace08	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace08(void)$/;"	f	file:
+testTrace08	test/sysUtils/tst_psTrace.c	/^static psS32 testTrace08(void);$/;"	p	file:
+testUnary	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^testDescription testUnary[] = {$/;"	v
+testUnaryOpM	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^    #define testUnaryOpM(/;"	d	file:
+testUnaryOpScalar	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^psS32 testUnaryOpScalar(void)$/;"	f
+testUnaryOpScalar	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^static psS32 testUnaryOpScalar(void);$/;"	p	file:
+testUnaryOpV	test/dataManip/tst_psMatrixVectorArithmetic02.c	/^    #define testUnaryOpV(/;"	d	file:
+testVectorComplex	test/dataManip/tst_psVectorFFT.c	/^psS32 testVectorComplex( void )$/;"	f
+testVectorComplex	test/dataManip/tst_psVectorFFT.c	/^static psS32 testVectorComplex( void );$/;"	p	file:
+testVectorConjugate	test/dataManip/tst_psVectorFFT.c	/^psS32 testVectorConjugate( void )$/;"	f
+testVectorConjugate	test/dataManip/tst_psVectorFFT.c	/^static psS32 testVectorConjugate( void );$/;"	p	file:
+testVectorFFT	test/dataManip/tst_psVectorFFT.c	/^psS32 testVectorFFT( void )$/;"	f
+testVectorFFT	test/dataManip/tst_psVectorFFT.c	/^static psS32 testVectorFFT( void );$/;"	p	file:
+testVectorPowerSpectrum	test/dataManip/tst_psVectorFFT.c	/^psS32 testVectorPowerSpectrum( void )$/;"	f
+testVectorPowerSpectrum	test/dataManip/tst_psVectorFFT.c	/^static psS32 testVectorPowerSpectrum( void );$/;"	p	file:
+testVectorRealImaginary	test/dataManip/tst_psVectorFFT.c	/^psS32 testVectorRealImaginary( void )$/;"	f
+testVectorRealImaginary	test/dataManip/tst_psVectorFFT.c	/^static psS32 testVectorRealImaginary( void );$/;"	p	file:
+tests	test/astronomy/tst_psAstrometry.c	/^testDescription tests[] = {$/;"	v
+tests	test/astronomy/tst_psAstrometry01.c	/^testDescription tests[] = {$/;"	v
+tests	test/astronomy/tst_psCoord.c	/^testDescription tests[] = {$/;"	v
+tests	test/collections/tst_psArray02.c	/^testDescription tests[] = {$/;"	v
+tests	test/collections/tst_psBitSet.c	/^testDescription tests[] = {$/;"	v
+tests	test/collections/tst_psList.c	/^testDescription tests[] = {$/;"	v
+tests	test/collections/tst_psScalar.c	/^testDescription tests[] = {$/;"	v
+tests	test/dataManip/tst_psVectorFFT.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImage.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageConvolve.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageExtraction.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageFFT.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageIO.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageInterpolate.c	/^testDescription tests[] = {$/;"	v
+tests	test/image/tst_psImageManip.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psAbort.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psError.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psLogMsg.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psMemory.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psStringCopy.c	/^testDescription tests[] = {$/;"	v
+tests	test/sysUtils/tst_psTrace.c	/^testDescription tests[] = {$/;"	v
+tests	test/tst_template.c	/^testDescription tests[] = {$/;"	v
+tests2	test/sysUtils/tst_psTrace.c	/^testDescription tests2[] = {$/;"	v
+testsBinary	test/dataManip/tst_psMatrixVectorArithmetic04.c	/^testDescription testsBinary[] = {$/;"	v
+time	include/psAstrometry.h	/^    const psTime* time;                \/\/\/< Time of observation$/;"	m	struct:psExposure
+time	src/astronomy/psAstrometry.h	/^    const psTime* time;                \/\/\/< Time of observation$/;"	m	struct:psExposure
+timeMetadata	src/astronomy/psTime.c	/^                static psMetadata *timeMetadata = NULL;$/;"	v	file:
+tlr	include/psAstrometry.h	/^    const double tlr;                  \/\/\/< Tropospheric Lapse Rate$/;"	m
+tlr	src/astronomy/psAstrometry.h	/^    const double tlr;                  \/\/\/< Tropospheric Lapse Rate$/;"	m
+toChip	include/psAstrometry.h	/^    psPlaneTransform* toChip;          \/\/\/< transformations from cell to chip coordinates$/;"	m
+toChip	src/astronomy/psAstrometry.h	/^    psPlaneTransform* toChip;          \/\/\/< transformations from cell to chip coordinates$/;"	m
+toFPA	include/psAstrometry.h	/^    psPlaneTransform* toFPA;           \/\/\/< transformation from chip to FPA coordinates$/;"	m	struct:psChip
+toFPA	include/psAstrometry.h	/^    psPlaneTransform* toFPA;           \/\/\/< transformations from cell to FPA coordinates$/;"	m
+toFPA	src/astronomy/psAstrometry.h	/^    psPlaneTransform* toFPA;           \/\/\/< transformation from chip to FPA coordinates$/;"	m	struct:psChip
+toFPA	src/astronomy/psAstrometry.h	/^    psPlaneTransform* toFPA;           \/\/\/< transformations from cell to FPA coordinates$/;"	m
+toSky	include/psAstrometry.h	/^    psPlaneTransform* toSky;            \/\/\/< transformations from cell to tangent plane coordinates$/;"	m
+toSky	src/astronomy/psAstrometry.h	/^    psPlaneTransform* toSky;            \/\/\/< transformations from cell to tangent plane coordinates$/;"	m
+toTP	include/psAstrometry.h	/^    psPlaneTransform* toTP;            \/\/\/< transformations from cell to tangent plane coordinates$/;"	m
+toTP	src/astronomy/psAstrometry.h	/^    psPlaneTransform* toTP;            \/\/\/< transformations from cell to tangent plane coordinates$/;"	m
+toTangentPlane	include/psAstrometry.h	/^    psPlaneDistort* toTangentPlane;    \/\/\/< transformation from focal plane to tangent plane$/;"	m	struct:psFPA
+toTangentPlane	src/astronomy/psAstrometry.h	/^    psPlaneDistort* toTangentPlane;    \/\/\/< transformation from focal plane to tangent plane$/;"	m	struct:psFPA
+tol	include/psMinimize.h	/^    psF32 tol;                         \/\/\/< Error Tolerance$/;"	m
+tol	src/dataManip/psMinimize.h	/^    psF32 tol;                         \/\/\/< Error Tolerance$/;"	m
+traceFP	src/sysUtils/psTrace.c	/^static FILE *traceFP = NULL;        \/\/ File destination for messages.$/;"	v	file:
+transform	include/psPhotometry.h	/^    psPolynomial3D transform;   \/\/\/< Transformation from source to destination$/;"	m
+transform	src/astronomy/psPhotometry.h	/^    psPolynomial3D transform;   \/\/\/< Transformation from source to destination$/;"	m
+tstScalarAllocByType	test/collections/tst_psScalar.c	/^#define tstScalarAllocByType(/;"	d	file:
+tstScalarCopyByType	test/collections/tst_psScalar.c	/^#define tstScalarCopyByType(/;"	d	file:
+tstVectorSortByType	test/collections/tst_psVectorSort_01.c	/^#define tstVectorSortByType(/;"	d	file:
+tstVectorSortIndexByType	test/collections/tst_psVectorSort_02.c	/^#define tstVectorSortIndexByType(/;"	d	file:
+type	include/psCoord.h	/^    psProjectionType type;      \/\/\/< Projection type$/;"	m
+type	include/psFunctions.h	/^    psPolynomialType type;             \/\/\/< Polynomial type$/;"	m
+type	include/psImage.h	/^    const psType type;                 \/\/\/< Image data type and dimension.$/;"	m	struct:psImage
+type	include/psMetadata.h	/^    psMetadataType type;               \/\/\/< Type of metadata item.$/;"	m	struct:psMetadataItem
+type	include/psRandom.h	/^    psRandomType type; \/\/\/< The type of RNG$/;"	m
+type	include/psScalar.h	/^    psType type;                \/\/\/< Type of data.$/;"	m
+type	include/psTime.h	/^    psTimeType type;    \/\/\/< Type of time.$/;"	m	struct:psTime
+type	include/psType.h	/^    psElemType type;            \/\/\/< Primitive type.$/;"	m
+type	include/psType.h	/^    psType  type;              \/\/\/< Data type information$/;"	m
+type	include/psVector.h	/^    psType type;                \/\/\/< Type of data.$/;"	m
+type	src/astronomy/psCoord.h	/^    psProjectionType type;      \/\/\/< Projection type$/;"	m
+type	src/astronomy/psMetadata.h	/^    psMetadataType type;               \/\/\/< Type of metadata item.$/;"	m	struct:psMetadataItem
+type	src/astronomy/psTime.h	/^    psTimeType type;    \/\/\/< Type of time.$/;"	m	struct:psTime
+type	src/collections/psScalar.h	/^    psType type;                \/\/\/< Type of data.$/;"	m
+type	src/collections/psVector.h	/^    psType type;                \/\/\/< Type of data.$/;"	m
+type	src/dataManip/psFunctions.h	/^    psPolynomialType type;             \/\/\/< Polynomial type$/;"	m
+type	src/dataManip/psRandom.h	/^    psRandomType type; \/\/\/< The type of RNG$/;"	m
+type	src/image/psImage.h	/^    const psType type;                 \/\/\/< Image data type and dimension.$/;"	m	struct:psImage
+type	src/sysUtils/psType.h	/^    psElemType type;            \/\/\/< Primitive type.$/;"	m
+type	src/sysUtils/psType.h	/^    psType  type;              \/\/\/< Data type information$/;"	m
+uniform	include/psStats.h	/^    psBool uniform;                      \/\/\/< Is it a uniform distribution?$/;"	m
+uniform	src/dataManip/psStats.h	/^    psBool uniform;                      \/\/\/< Is it a uniform distribution?$/;"	m
+usec	include/psTime.h	/^    psU32 usec;         \/\/\/< Microseconds since last second.$/;"	m	struct:psTime
+usec	src/astronomy/psTime.h	/^    psU32 usec;         \/\/\/< Microseconds since last second.$/;"	m	struct:psTime
+userMemorySize	include/psMemory.h	/^    size_t userMemorySize;             \/\/\/< the size of the user-portion of the memory block$/;"	m	struct:psMemBlock
+userMemorySize	src/sysUtils/psMemory.h	/^    size_t userMemorySize;             \/\/\/< the size of the user-portion of the memory block$/;"	m	struct:psMemBlock
+validFrom	include/psLookupTable.h	/^    psF64 validFrom;                   \/\/\/< Lower bound for rable read$/;"	m
+validFrom	src/fileUtils/psLookupTable.h	/^    psF64 validFrom;                   \/\/\/< Lower bound for rable read$/;"	m
+validTo	include/psLookupTable.h	/^    psF64 validTo;                     \/\/\/< Upper bound for table read$/;"	m
+validTo	src/fileUtils/psLookupTable.h	/^    psF64 validTo;                     \/\/\/< Upper bound for table read$/;"	m
+value	include/psMinimize.h	/^    psF32 value;                       \/\/\/< Value of function at minimum$/;"	m
+value	src/dataManip/psMinimize.h	/^    psF32 value;                       \/\/\/< Value of function at minimum$/;"	m
+values	include/psLookupTable.h	/^    psArray *values;                   \/\/\/< Array of dependent table values corresponding to index values$/;"	m
+values	src/fileUtils/psLookupTable.h	/^    psArray *values;                   \/\/\/< Array of dependent table values corresponding to index values$/;"	m
+vectorBinDisectF32	src/dataManip/psFunctions.c	/^static psS32 vectorBinDisectF32(psF32 *bins,psS32 numBins,psF32 x);$/;"	p	file:
+vectorBinDisectS32	src/dataManip/psFunctions.c	/^static psS32 vectorBinDisectS32(psS32 *bins,psS32 numBins,psS32 x);$/;"	p	file:
+vectorFree	src/collections/psVector.c	/^static void vectorFree(psVector* restrict psVec)$/;"	f	file:
+vectorFree	src/collections/psVector.c	/^static void vectorFree(psVector* restrict psVec);$/;"	p	file:
+wavelength	include/psAstrometry.h	/^    const double wavelength;           \/\/\/< wavelength (WL)$/;"	m
+wavelength	include/psAstrometry.h	/^    const float wavelength;            \/\/\/< Wavelength in microns$/;"	m	struct:psExposure
+wavelength	src/astronomy/psAstrometry.h	/^    const double wavelength;           \/\/\/< wavelength (WL)$/;"	m
+wavelength	src/astronomy/psAstrometry.h	/^    const float wavelength;            \/\/\/< Wavelength in microns$/;"	m	struct:psExposure
+worm	test/FullUnitTest	/^sub worm {$/;"	s
+worm	testbin/FullUnitTest	/^sub worm {$/;"	s
+x	include/psAstrometry.h	/^    double **x;                        \/\/\/< The grid of offsets in x$/;"	m
+x	include/psCoord.h	/^    double x;                   \/\/\/< x position$/;"	m
+x	include/psCoord.h	/^    psDPolynomial2D* x;         \/\/\/< 2D polynomial transform of X coordinates$/;"	m
+x	include/psCoord.h	/^    psDPolynomial4D* x;         \/\/\/< 4D polynomial transform of X coordinates$/;"	m
+x	src/astronomy/psAstrometry.h	/^    double **x;                        \/\/\/< The grid of offsets in x$/;"	m
+x	src/astronomy/psCoord.h	/^    double x;                   \/\/\/< x position$/;"	m
+x	src/astronomy/psCoord.h	/^    psDPolynomial2D* x;         \/\/\/< 2D polynomial transform of X coordinates$/;"	m
+x	src/astronomy/psCoord.h	/^    psDPolynomial4D* x;         \/\/\/< 4D polynomial transform of X coordinates$/;"	m
+x	test/collections/tst_psArray.c	/^    psS32 x;$/;"	m	file:
+x	test/collections/tst_psArray01.c	/^    psS32 x;$/;"	m	file:
+x0	include/psAstrometry.h	/^    double x0;                         \/\/\/< X Position of 0,0 corner on focal plane$/;"	m
+x0	include/psImage.h	/^    double x0;                         \/\/\/< the first column of the region.$/;"	m
+x0	src/astronomy/psAstrometry.h	/^    double x0;                         \/\/\/< X Position of 0,0 corner on focal plane$/;"	m
+x0	src/image/psImage.h	/^    double x0;                         \/\/\/< the first column of the region.$/;"	m
+x1	include/psImage.h	/^    double x1;                         \/\/\/< the last column of the region.$/;"	m
+x1	src/image/psImage.h	/^    double x1;                         \/\/\/< the last column of the region.$/;"	m
+xErr	include/psCoord.h	/^    double xErr;                \/\/\/< Error in x position$/;"	m
+xErr	src/astronomy/psCoord.h	/^    double xErr;                \/\/\/< Error in x position$/;"	m
+xMax	include/psImageConvolve.h	/^    psS32 xMax;                          \/\/\/< Most positive x index$/;"	m
+xMax	src/image/psImageConvolve.h	/^    psS32 xMax;                          \/\/\/< Most positive x index$/;"	m
+xMin	include/psImageConvolve.h	/^    psS32 xMin;                          \/\/\/< Most negative x index$/;"	m
+xMin	src/image/psImageConvolve.h	/^    psS32 xMin;                          \/\/\/< Most negative x index$/;"	m
+xScale	include/psAstrometry.h	/^    double xScale;                     \/\/\/< Scale of the grid in x direction$/;"	m
+xScale	src/astronomy/psAstrometry.h	/^    double xScale;                     \/\/\/< Scale of the grid in x direction$/;"	m
+y	include/psAstrometry.h	/^    double **y;                        \/\/\/< The grid of offsets in y$/;"	m
+y	include/psCoord.h	/^    double y;                   \/\/\/< y position$/;"	m
+y	include/psCoord.h	/^    psDPolynomial2D* y;         \/\/\/< 2D polynomial transform of Y coordinates$/;"	m
+y	include/psCoord.h	/^    psDPolynomial4D* y;         \/\/\/< 4D polynomial transform of Y coordinates$/;"	m
+y	src/astronomy/psAstrometry.h	/^    double **y;                        \/\/\/< The grid of offsets in y$/;"	m
+y	src/astronomy/psCoord.h	/^    double y;                   \/\/\/< y position$/;"	m
+y	src/astronomy/psCoord.h	/^    psDPolynomial2D* y;         \/\/\/< 2D polynomial transform of Y coordinates$/;"	m
+y	src/astronomy/psCoord.h	/^    psDPolynomial4D* y;         \/\/\/< 4D polynomial transform of Y coordinates$/;"	m
+y	src/astronomy/psMetadataIO.c	/^    int y;$/;"	m	file:
+y	test/collections/tst_psArray.c	/^    float y;$/;"	m	file:
+y	test/collections/tst_psArray01.c	/^    float y;$/;"	m	file:
+y0	include/psAstrometry.h	/^    double y0;                         \/\/\/< Y Position of 0,0 corner on focal plane$/;"	m
+y0	include/psImage.h	/^    double y0;                         \/\/\/< the first row of the region.$/;"	m
+y0	src/astronomy/psAstrometry.h	/^    double y0;                         \/\/\/< Y Position of 0,0 corner on focal plane$/;"	m
+y0	src/image/psImage.h	/^    double y0;                         \/\/\/< the first row of the region.$/;"	m
+y1	include/psImage.h	/^    double y1;                         \/\/\/< the last row of the region.$/;"	m
+y1	src/image/psImage.h	/^    double y1;                         \/\/\/< the last row of the region.$/;"	m
+yErr	include/psCoord.h	/^    double yErr;                \/\/\/< Error in y position$/;"	m
+yErr	src/astronomy/psCoord.h	/^    double yErr;                \/\/\/< Error in y position$/;"	m
+yMax	include/psImageConvolve.h	/^    psS32 yMax;                          \/\/\/< Most positive y index$/;"	m
+yMax	src/image/psImageConvolve.h	/^    psS32 yMax;                          \/\/\/< Most positive y index$/;"	m
+yMin	include/psImageConvolve.h	/^    psS32 yMin;                          \/\/\/< Most negative y index$/;"	m
+yMin	src/image/psImageConvolve.h	/^    psS32 yMin;                          \/\/\/< Most negative y index$/;"	m
+yScale	include/psAstrometry.h	/^    double yScale;                     \/\/\/< Scale of the grid in x direction$/;"	m
+yScale	src/astronomy/psAstrometry.h	/^    double yScale;                     \/\/\/< Scale of the grid in x direction$/;"	m
+zenithDistance	include/psAstrometry.h	/^    const double zenithDistance;       \/\/\/< Zenith distance$/;"	m	struct:psExposure
+zenithDistance	src/astronomy/psAstrometry.h	/^    const double zenithDistance;       \/\/\/< Zenith distance$/;"	m	struct:psExposure
Index: /branches/rel4/psLib/test/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/.cvsignore	(revision 3057)
@@ -0,0 +1,3 @@
+temp
+tst_psTime_01
+tst_psTime_02
Index: /branches/rel4/psLib/test/FullUnitTest
===================================================================
--- /branches/rel4/psLib/test/FullUnitTest	(revision 3057)
+++ /branches/rel4/psLib/test/FullUnitTest	(revision 3057)
@@ -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.15 $  $Name: not supported by cvs2svn $
+#  $Date: 2004-10-27 00:57:31 $
+#
+#  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 psS64 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/rel4/psLib/test/Makefile
===================================================================
--- /branches/rel4/psLib/test/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/Makefile	(revision 3057)
@@ -0,0 +1,106 @@
+##############################################################################
+##
+##  Makefile:   test
+##
+##  $Revision: 1.10 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-11-09 01:10:38 $
+##
+##  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
+	$(MAKE) --directory=fileUtils 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
+	$(MAKE) --directory=astronomy distclean
+	$(MAKE) --directory=fileUtils 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
+	$(MAKE) --directory=astronomy clean
+	$(MAKE) --directory=fileUtils 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/rel4/psLib/test/astronomy/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/astronomy/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/.cvsignore	(revision 3057)
@@ -0,0 +1,17 @@
+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
+tst_psMetadata_07
+tst_psTime_03
+tst_psTime_04
Index: /branches/rel4/psLib/test/astronomy/Makefile
===================================================================
--- /branches/rel4/psLib/test/astronomy/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/Makefile	(revision 3057)
@@ -0,0 +1,57 @@
+################################################################################
+##
+##  Makefile:   test/astronomy
+##
+##  $Revision: 1.25 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-07 23:52:00 $
+##
+##  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 -I/usr/include/libxml $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest -lxml2 $(LDFLAGS)
+
+TARGET = tst_psTime_01 \
+         tst_psTime_02 \
+         tst_psTime_03 \
+         tst_psTime_04 \
+         tst_psMetadataIO  \
+         tst_psMetadata_01 \
+         tst_psMetadata_02 \
+         tst_psMetadata_03 \
+         tst_psMetadata_04 \
+         tst_psMetadata_05 \
+         tst_psMetadata_06 \
+         tst_psMetadata_07 \
+         tst_psAstrometry \
+         tst_psCoord \
+         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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_01.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_01.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_01.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_02.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_02.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_02.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_03.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_03.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_03.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_04.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_04.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_04.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_05.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_05.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_05.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psMetadata_06.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_06.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psMetadata_06.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psTime_01.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psTime_01.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psTime_01.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/builddir/tst_psTime_02.d
===================================================================
--- /branches/rel4/psLib/test/astronomy/builddir/tst_psTime_02.d	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/builddir/tst_psTime_02.d	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/header_1.fits
===================================================================
--- /branches/rel4/psLib/test/astronomy/header_1.fits	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/header_1.fits	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/header_2.fits
===================================================================
--- /branches/rel4/psLib/test/astronomy/header_2.fits	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/header_2.fits	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/test.config
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.config	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.config	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/test.psTime.config
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR ../../dataxz                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR ser7.dat eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 53258.0, 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config1
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config1	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config1	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR ../../dataxz                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR ser7.dat eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 53258.0, 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config1.template
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config1.template	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config1.template	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR bogus                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR ser7.dat eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 53258.0, 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config2
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config2	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config2	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR ../../data                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 53258.0, 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config2.template
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config2.template	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config2.template	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR PREFIX/data                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 53258.0, 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config3
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config3	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config3	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR ../../data                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR ser7.dat eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config3.template
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config3.template	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config3.template	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR PREFIX/data                                                    # Directory for time tables
+psLib.time.tables.n S32 4                                                               # Number of time tables
+psLib.time.tables.files STR ser7.dat eopc01_1900_2004.dat finals_all.dat tai_utc.dat    # These are the table file names
+@psLib.time.tables.from F64 15020.0, 41684.0 2437300.5                         # Valid from these dates
+@psLib.time.tables.to F64 53622.0, 53258.0, 53627.0 2451179.5                           # Valid to these dates
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569, 0.0555, -0.0200, 0.0513, 0.1483
+@psLib.time.predict.yp F64 0.3498, -0.0176, -0.0498, 0.1483, -0.0513
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944, -0.00023, 53262.0
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config4
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config4	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config4	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR .                                                             # Directory for time tables
+psLib.time.tables.n S32 1                                                               # Number of time tables
+psLib.time.tables.files STR test.ser7.dat                                               # This the table file
+@psLib.time.tables.from F64 53258.0                                                     # Valid from this date
+@psLib.time.tables.to F64 53622.0                                                       # Valid to this date
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569
+@psLib.time.predict.yp F64 0.3498
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944
+
Index: /branches/rel4/psLib/test/astronomy/test.psTime.config4.template
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.psTime.config4.template	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.psTime.config4.template	(revision 3057)
@@ -0,0 +1,23 @@
+# This configuration file specifies values required for time calculations by psLib.
+psLib.time.tables.dir STR .                                                             # Directory for time tables
+psLib.time.tables.n S32 1                                                               # Number of time tables
+psLib.time.tables.files STR test.ser7.dat                                               # This the table file
+@psLib.time.tables.from F64 53258.0                                                     # Valid from this date
+@psLib.time.tables.to F64 53622.0                                                       # Valid to this date
+psLib.time.before.xp F64 0.0                                                            # Value of XP for before the earliest MJD
+psLib.time.before.yp F64 0.0                                                            # Value of YP for before the earliest MJD
+psLib.time.before.dut F64 0.0                                                           # Value of UT1-UTC for before the earliest MJD
+
+# Now follows formulae for predicting ahead of the most recent available table entry.
+# xp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# yp = [0] + [1]*cos A + [2]*sin A + [3]*cos C + [4]*sin C
+# A = 2*pi*(MJD - pslib.time.predict.mjd)/365.25
+# C = 2*pi*(MJD - pslib.time.predict.mjd)/435.0
+# dut = ut1-utc = [0] + [1]*(MJD - [2]) - (UT2-UT1)
+# ut2-ut1 = 0.022 sin(2*pi*T) - 0.012 cos(2*pi*T) - 0.006 sin(4*pi*T) + 0.007 cos(4*pi*T)
+# T = 2000.0 + (MJD - 51544.03)/365.2422
+@psLib.time.predict.xp F64 0.0569
+@psLib.time.predict.yp F64 0.3498
+psLib.time.predict.mjd F64 53257.0
+@psLib.time.predict.dut F64 -0.4944
+
Index: /branches/rel4/psLib/test/astronomy/test.ser7.dat
===================================================================
--- /branches/rel4/psLib/test/astronomy/test.ser7.dat	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/test.ser7.dat	(revision 3057)
@@ -0,0 +1,380 @@
+#  ser7.dat
+#
+#  This file comes from http://maia.usno.navy.mil (Click on General Information about Earth Orientation). This
+#  file may also be directly downloaded from ftp://maia.usno.navy.mil/ser7/ser7.dat. See readme.ser7 (located
+#  in the psLib/data directory) for details.
+#
+#  @author Ross Harman, MHPCC
+#
+#  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+#  @date $Date: 2004-11-15 20:14:44 $
+#
+#
+#        MJD         PM-x        PM-y       UT1-UTC
+#      (days)      (arcsec)    (arcsec)      (sec)
+        psF64        psF64       psF64       psF64
+        53yyy244       0.1377      0.5027     -0.45210
+        53245       0.1394      0.5015     -0.45190
+        53246       0.1411      0.5002     -0.45197
+        53247       0.1429      0.4989     -0.45234
+        53248       0.1447      0.4976     -0.45293
+        53249       0.1465      0.4962     -0.45361
+        53250       0.1484      0.4948     -0.45424
+        53251       0.1503      0.4934     -0.45476
+        53252       0.1521      0.4920     -0.45512
+        53253       0.1540      0.4905     -0.45530
+        53254       0.1558      0.4890     -0.45531
+        53255       0.1577      0.4874     -0.45519
+        53256       0.1595      0.4859     -0.45497
+        53257       0.1613      0.4843     -0.45474
+        53258       0.1631      0.4827     -0.45458
+        53259       0.1649      0.4810     -0.45456
+        53260       0.1667      0.4794     -0.45474
+        53261       0.1684      0.4777     -0.45514
+        53262       0.1701      0.4760     -0.45578
+        53263       0.1717      0.4742     -0.45660
+        53264       0.1734      0.4725     -0.45754
+        53265       0.1750      0.4707     -0.45849
+        53266       0.1765      0.4689     -0.45932
+        53267       0.1780      0.4671     -0.45996
+        53268       0.1795      0.4652     -0.46036
+        53269       0.1810      0.4634     -0.46055
+        53270       0.1824      0.4615     -0.46061
+        53271       0.1838      0.4596     -0.46068
+        53272       0.1852      0.4576     -0.46086
+        53273       0.1865      0.4557     -0.46126
+        53274       0.1878      0.4537     -0.46192
+        53275       0.1890      0.4517     -0.46280
+        53276       0.1902      0.4497     -0.46382
+        53277       0.1914      0.4477     -0.46486
+        53278       0.1925      0.4457     -0.46581
+        53279       0.1936      0.4436     -0.46658
+        53280       0.1946      0.4415     -0.46715
+        53281       0.1956      0.4394     -0.46750
+        53282       0.1966      0.4373     -0.46766
+        53283       0.1976      0.4352     -0.46772
+        53284       0.1985      0.4331     -0.46773
+        53285       0.1993      0.4309     -0.46778
+        53286       0.2001      0.4288     -0.46795
+        53287       0.2009      0.4266     -0.46830
+        53288       0.2017      0.4244     -0.46887
+        53289       0.2024      0.4222     -0.46968
+        53290       0.2031      0.4200     -0.47071
+        53291       0.2037      0.4178     -0.47191
+        53292       0.2043      0.4155     -0.47317
+        53293       0.2049      0.4133     -0.47435
+        53294       0.2054      0.4111     -0.47536
+        53295       0.2059      0.4088     -0.47610
+        53296       0.2063      0.4065     -0.47659
+        53297       0.2067      0.4042     -0.47691
+        53298       0.2071      0.4020     -0.47718
+        53299       0.2075      0.3997     -0.47755
+        53300       0.2078      0.3974     -0.47811
+        53301       0.2080      0.3951     -0.47893
+        53302       0.2083      0.3928     -0.47998
+        53303       0.2085      0.3905     -0.48119
+        53304       0.2086      0.3881     -0.48247
+        53305       0.2088      0.3858     -0.48369
+        53306       0.2089      0.3835     -0.48477
+        53307       0.2089      0.3812     -0.48565
+        53308       0.2090      0.3789     -0.48630
+        53309       0.2089      0.3765     -0.48674
+        53310       0.2089      0.3742     -0.48701
+        53311       0.2088      0.3719     -0.48718
+        53312       0.2088      0.3696     -0.48732
+        53313       0.2086      0.3672     -0.48753
+        53314       0.2085      0.3649     -0.48785
+        53315       0.2082      0.3626     -0.48835
+        53316       0.2080      0.3603     -0.48906
+        53317       0.2077      0.3579     -0.48997
+        53318       0.2074      0.3556     -0.49106
+        53319       0.2071      0.3533     -0.49226
+        53320       0.2067      0.3510     -0.49344
+        53321       0.2063      0.3487     -0.49449
+        53322       0.2059      0.3464     -0.49531
+        53323       0.2054      0.3441     -0.49585
+        53324       0.2049      0.3418     -0.49618
+        53325       0.2044      0.3396     -0.49639
+        53326       0.2038      0.3373     -0.49664
+        53327       0.2032      0.3350     -0.49705
+        53328       0.2026      0.3328     -0.49769
+        53329       0.2020      0.3305     -0.49854
+        53330       0.2013      0.3283     -0.49953
+        53331       0.2006      0.3261     -0.50058
+        53332       0.1999      0.3239     -0.50158
+        53333       0.1991      0.3217     -0.50243
+        53334       0.1983      0.3195     -0.50308
+        53335       0.1975      0.3173     -0.50350
+        53336       0.1967      0.3151     -0.50369
+        53337       0.1958      0.3130     -0.50370
+        53338       0.1949      0.3108     -0.50358
+        53339       0.1940      0.3087     -0.50342
+        53340       0.1931      0.3066     -0.50329
+        53341       0.1921      0.3045     -0.50327
+        53342       0.1911      0.3024     -0.50340
+        53343       0.1901      0.3004     -0.50372
+        53344       0.1890      0.2983     -0.50423
+        53345       0.1880      0.2963     -0.50493
+        53346       0.1869      0.2943     -0.50574
+        53347       0.1858      0.2923     -0.50660
+        53348       0.1846      0.2903     -0.50739
+        53349       0.1835      0.2883     -0.50808
+        53350       0.1823      0.2864     -0.50851
+        53351       0.1811      0.2844     -0.50870
+        53352       0.1799      0.2825     -0.50874
+        53353       0.1786      0.2807     -0.50875
+        53354       0.1773      0.2788     -0.50890
+        53355       0.1760      0.2769     -0.50927
+        53356       0.1747      0.2751     -0.50987
+        53357       0.1734      0.2733     -0.51064
+        53358       0.1720      0.2715     -0.51148
+        53359       0.1707      0.2698     -0.51228
+        53360       0.1693      0.2680     -0.51295
+        53361       0.1679      0.2663     -0.51342
+        53362       0.1664      0.2646     -0.51367
+        53363       0.1650      0.2629     -0.51371
+        53364       0.1635      0.2613     -0.51357
+        53365       0.1620      0.2596     -0.51330
+        53366       0.1605      0.2580     -0.51298
+        53367       0.1590      0.2565     -0.51268
+        53368       0.1575      0.2549     -0.51247
+        53369       0.1559      0.2534     -0.51241
+        53370       0.1543      0.2519     -0.51253
+        53371       0.1528      0.2504     -0.51283
+        53372       0.1511      0.2489     -0.51331
+        53373       0.1495      0.2475     -0.51391
+        53374       0.1479      0.2461     -0.51458
+        53375       0.1463      0.2447     -0.51522
+        53376       0.1446      0.2434     -0.51574
+        53377       0.1429      0.2420     -0.51605
+        53378       0.1412      0.2407     -0.51614
+        53379       0.1395      0.2395     -0.51605
+        53380       0.1378      0.2382     -0.51590
+        53381       0.1361      0.2370     -0.51585
+        53382       0.1344      0.2358     -0.51603
+        53383       0.1326      0.2347     -0.51648
+        53384       0.1308      0.2335     -0.51717
+        53385       0.1291      0.2324     -0.51800
+        53386       0.1273      0.2313     -0.51881
+        53387       0.1255      0.2303     -0.51951
+        53388       0.1237      0.2293     -0.52000
+        53389       0.1219      0.2283     -0.52027
+        53390       0.1200      0.2273     -0.52032
+        53391       0.1182      0.2264     -0.52018
+        53392       0.1164      0.2255     -0.51992
+        53393       0.1145      0.2246     -0.51959
+        53394       0.1126      0.2237     -0.51928
+        53395       0.1108      0.2229     -0.51905
+        53396       0.1089      0.2221     -0.51897
+        53397       0.1070      0.2213     -0.51908
+        53398       0.1051      0.2206     -0.51939
+        53399       0.1032      0.2199     -0.51987
+        53400       0.1013      0.2192     -0.52050
+        53401       0.0994      0.2186     -0.52119
+        53402       0.0975      0.2180     -0.52187
+        53403       0.0956      0.2174     -0.52246
+        53404       0.0936      0.2168     -0.52288
+        53405       0.0917      0.2163     -0.52309
+        53406       0.0898      0.2158     -0.52311
+        53407       0.0878      0.2153     -0.52305
+        53408       0.0859      0.2149     -0.52303
+        53409       0.0840      0.2144     -0.52321
+        53410       0.0820      0.2141     -0.52368
+        53411       0.0801      0.2137     -0.52444
+        53412       0.0781      0.2134     -0.52542
+        53413       0.0761      0.2131     -0.52646
+        53414       0.0742      0.2128     -0.52744
+        53415       0.0722      0.2126     -0.52822
+        53416       0.0703      0.2124     -0.52877
+        53417       0.0683      0.2122     -0.52907
+        53418       0.0663      0.2120     -0.52916
+        53419       0.0644      0.2119     -0.52910
+        53420       0.0624      0.2118     -0.52897
+        53421       0.0605      0.2117     -0.52883
+        53422       0.0585      0.2117     -0.52876
+        53423       0.0566      0.2117     -0.52882
+        53424       0.0546      0.2117     -0.52907
+        53425       0.0526      0.2118     -0.52951
+        53426       0.0507      0.2118     -0.53014
+        53427       0.0487      0.2119     -0.53091
+        53428       0.0468      0.2121     -0.53174
+        53429       0.0449      0.2122     -0.53254
+        53430       0.0429      0.2124     -0.53321
+        53431       0.0410      0.2126     -0.53368
+        53432       0.0391      0.2129     -0.53392
+        53433       0.0372      0.2131     -0.53393
+        53434       0.0352      0.2134     -0.53380
+        53435       0.0333      0.2138     -0.53366
+        53436       0.0314      0.2141     -0.53365
+        53437       0.0296      0.2145     -0.53389
+        53438       0.0277      0.2149     -0.53443
+        53439       0.0258      0.2154     -0.53526
+        53440       0.0239      0.2159     -0.53627
+        53441       0.0221      0.2164     -0.53733
+        53442       0.0202      0.2169     -0.53830
+        53443       0.0184      0.2174     -0.53908
+        53444       0.0166      0.2180     -0.53964
+        53445       0.0147      0.2186     -0.53998
+        53446       0.0129      0.2192     -0.54014
+        53447       0.0111      0.2198     -0.54018
+        53448       0.0093      0.2205     -0.54018
+        53449       0.0076      0.2212     -0.54022
+        53450       0.0058      0.2219     -0.54037
+        53451       0.0040      0.2227     -0.54069
+        53452       0.0023      0.2234     -0.54118
+        53453       0.0005      0.2242     -0.54185
+        53454      -0.0012      0.2250     -0.54266
+        53455      -0.0029      0.2258     -0.54356
+        53456      -0.0046      0.2267     -0.54447
+        53457      -0.0063      0.2276     -0.54530
+        53458      -0.0079      0.2285     -0.54598
+        53459      -0.0096      0.2294     -0.54647
+        53460      -0.0112      0.2303     -0.54675
+        53461      -0.0128      0.2313     -0.54688
+        53462      -0.0144      0.2323     -0.54699
+        53463      -0.0160      0.2333     -0.54724
+        53464      -0.0176      0.2343     -0.54775
+        53465      -0.0191      0.2353     -0.54858
+        53466      -0.0207      0.2364     -0.54970
+        53467      -0.0222      0.2375     -0.55097
+        53468      -0.0237      0.2386     -0.55228
+        53469      -0.0252      0.2397     -0.55354
+        53470      -0.0267      0.2408     -0.55465
+        53471      -0.0281      0.2420     -0.55556
+        53472      -0.0295      0.2431     -0.55626
+        53473      -0.0310      0.2443     -0.55677
+        53474      -0.0323      0.2455     -0.55715
+        53475      -0.0337      0.2468     -0.55748
+        53476      -0.0351      0.2480     -0.55785
+        53477      -0.0364      0.2493     -0.55833
+        53478      -0.0377      0.2505     -0.55899
+        53479      -0.0390      0.2518     -0.55988
+        53480      -0.0403      0.2531     -0.56095
+        53481      -0.0415      0.2545     -0.56216
+        53482      -0.0427      0.2558     -0.56347
+        53483      -0.0439      0.2572     -0.56478
+        53484      -0.0451      0.2585     -0.56599
+        53485      -0.0463      0.2599     -0.56699
+        53486      -0.0474      0.2613     -0.56769
+        53487      -0.0485      0.2627     -0.56808
+        53488      -0.0496      0.2641     -0.56824
+        53489      -0.0507      0.2656     -0.56830
+        53490      -0.0517      0.2670     -0.56839
+        53491      -0.0527      0.2685     -0.56860
+        53492      -0.0537      0.2700     -0.56897
+        53493      -0.0547      0.2714     -0.56955
+        53494      -0.0556      0.2729     -0.57032
+        53495      -0.0565      0.2744     -0.57119
+        53496      -0.0574      0.2760     -0.57204
+        53497      -0.0583      0.2775     -0.57277
+        53498      -0.0591      0.2790     -0.57329
+        53499      -0.0600      0.2806     -0.57354
+        53500      -0.0607      0.2821     -0.57350
+        53501      -0.0615      0.2837     -0.57328
+        53502      -0.0622      0.2853     -0.57298
+        53503      -0.0630      0.2869     -0.57261
+        53504      -0.0636      0.2885     -0.57218
+        53505      -0.0643      0.2901     -0.57175
+        53506      -0.0649      0.2917     -0.57143
+        53507      -0.0655      0.2933     -0.57124
+        53508      -0.0661      0.2949     -0.57117
+        53509      -0.0667      0.2966     -0.57124
+        53510      -0.0672      0.2982     -0.57139
+        53511      -0.0677      0.2999     -0.57158
+        53512      -0.0682      0.3015     -0.57166
+        53513      -0.0686      0.3032     -0.57155
+        53514      -0.0690      0.3048     -0.57116
+        53515      -0.0694      0.3065     -0.57057
+        53516      -0.0698      0.3082     -0.56989
+        53517      -0.0701      0.3098     -0.56921
+        53518      -0.0704      0.3115     -0.56860
+        53519      -0.0707      0.3132     -0.56818
+        53520      -0.0710      0.3149     -0.56799
+        53521      -0.0712      0.3166     -0.56800
+        53522      -0.0714      0.3183     -0.56809
+        53523      -0.0716      0.3200     -0.56815
+        53524      -0.0717      0.3217     -0.56808
+        53525      -0.0718      0.3234     -0.56781
+        53526      -0.0719      0.3251     -0.56728
+        53527      -0.0720      0.3268     -0.56651
+        53528      -0.0720      0.3285     -0.56557
+        53529      -0.0720      0.3302     -0.56454
+        53530      -0.0720      0.3319     -0.56347
+        53531      -0.0720      0.3336     -0.56244
+        53532      -0.0719      0.3353     -0.56148
+        53533      -0.0718      0.3370     -0.56060
+        53534      -0.0717      0.3387     -0.55990
+        53535      -0.0715      0.3404     -0.55943
+        53536      -0.0713      0.3421     -0.55916
+        53537      -0.0711      0.3438     -0.55897
+        53538      -0.0709      0.3455     -0.55881
+        53539      -0.0707      0.3472     -0.55859
+        53540      -0.0704      0.3489     -0.55820
+        53541      -0.0701      0.3506     -0.55751
+        53542      -0.0697      0.3523     -0.55650
+        53543      -0.0694      0.3540     -0.55529
+        53544      -0.0690      0.3557     -0.55402
+        53545      -0.0686      0.3573     -0.55279
+        53546      -0.0682      0.3590     -0.55173
+        53547      -0.0677      0.3607     -0.55093
+        53548      -0.0673      0.3623     -0.55037
+        53549      -0.0668      0.3640     -0.54994
+        53550      -0.0662      0.3656     -0.54947
+        53551      -0.0657      0.3673     -0.54884
+        53552      -0.0651      0.3689     -0.54798
+        53553      -0.0645      0.3705     -0.54689
+        53554      -0.0639      0.3721     -0.54560
+        53555      -0.0633      0.3738     -0.54414
+        53556      -0.0626      0.3754     -0.54257
+        53557      -0.0620      0.3770     -0.54101
+        53558      -0.0613      0.3786     -0.53952
+        53559      -0.0605      0.3801     -0.53819
+        53560      -0.0598      0.3817     -0.53705
+        53561      -0.0590      0.3833     -0.53611
+        53562      -0.0583      0.3848     -0.53535
+        53563      -0.0575      0.3864     -0.53475
+        53564      -0.0566      0.3879     -0.53425
+        53565      -0.0558      0.3895     -0.53374
+        53566      -0.0549      0.3910     -0.53315
+        53567      -0.0541      0.3925     -0.53243
+        53568      -0.0532      0.3940     -0.53152
+        53569      -0.0523      0.3955     -0.53042
+        53570      -0.0513      0.3969     -0.52913
+        53571      -0.0504      0.3984     -0.52776
+        53572      -0.0494      0.3998     -0.52644
+        53573      -0.0485      0.4013     -0.52532
+        53574      -0.0475      0.4027     -0.52451
+        53575      -0.0464      0.4041     -0.52400
+        53576      -0.0454      0.4055     -0.52377
+        53577      -0.0444      0.4069     -0.52366
+        53578      -0.0433      0.4083     -0.52344
+        53579      -0.0423      0.4096     -0.52299
+        53580      -0.0412      0.4110     -0.52228
+        53581      -0.0401      0.4123     -0.52130
+        53582      -0.0390      0.4136     -0.52010
+        53583      -0.0378      0.4149     -0.51872
+        53584      -0.0367      0.4162     -0.51725
+        53585      -0.0356      0.4175     -0.51578
+        53586      -0.0344      0.4188     -0.51436
+        53587      -0.0332      0.4200     -0.51310
+        53588      -0.0320      0.4212     -0.51204
+        53589      -0.0309      0.4224     -0.51120
+        53590      -0.0297      0.4236     -0.51055
+        53591      -0.0284      0.4248     -0.51006
+        53592      -0.0272      0.4260     -0.50966
+        53593      -0.0260      0.4271     -0.50922
+        53594      -0.0247      0.4283     -0.50872
+        53595      -0.0235      0.4294     -0.50809
+        53596      -0.0222      0.4305     -0.50729
+        53597      -0.0210      0.4315     -0.50638
+        53598      -0.0197      0.4326     -0.50535
+        53599      -0.0184      0.4336     -0.50431
+        53600      -0.0171      0.4347     -0.50339
+        53601      -0.0158      0.4357     -0.50273
+        53602      -0.0145      0.4367     -0.50244
+        53603      -0.0132      0.4376     -0.50247
+        53604      -0.0119      0.4386     -0.50267
+        53605      -0.0106      0.4395     -0.50286
+        53606      -0.0093      0.4404     -0.50287
+        53607      -0.0079      0.4413     -0.50263
+        53608      -0.0066      0.4422     -0.50217
Index: /branches/rel4/psLib/test/astronomy/tst_psAstrometry.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psAstrometry.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psAstrometry.c	(revision 3057)
@@ -0,0 +1,784 @@
+/** @file  tst_psAstrometry.c
+ *
+ *  @brief Contains the tests for psAstrometry.[ch]
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-14 01:46:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 testExposureAlloc(void);
+static psS32 testObservatoryAlloc(void);
+static psS32 testFPAAlloc(void);
+static psS32 testChipAlloc(void);
+static psS32 testCellAlloc(void);
+static psS32 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}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+static psS32 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(exp);
+    psFree(now);
+    psFree(obs);
+    psLibFinalize();
+    return 0;
+}
+
+static psS32 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 psS32 testFPAAlloc(void)
+{
+
+    psTime* now = psTimeGetTime(PS_TIME_TAI);
+    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 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the number of chips properly.");
+        return 4;
+    }
+
+    if (fpa->chips->nalloc != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not allocate space for the number of chips properly.");
+        return 4;
+    }
+
+    for (psS32 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;
+    }
+
+    if (fpa2->chips->nalloc != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the nalloc 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.
+    */
+
+    fpa->chips->n = fpa->chips->nalloc;
+    for (psS32 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);
+    psLibFinalize();
+
+    return 0;
+}
+
+static psS32 testChipAlloc(void)
+{
+    char* name = "The Kaiser Royal Observatory";
+
+    psTime* now = psTimeGetTime(PS_TIME_TAI);
+
+    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 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the number of cells properly.");
+        return 2;
+    }
+
+    if (chip->cells->nalloc != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not allocate cell array size properly.");
+        return 2;
+    }
+
+    for (psS32 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.
+    }
+    chip->cells->n = 8;
+
+    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 one.
+    */
+
+    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->cells->nalloc != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not allocate cell array size 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 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the number of cells properly.");
+        return 22;
+    }
+
+    if (chip3->cells->nalloc != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not allocate cell array properly.");
+        return 23;
+    }
+
+    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);
+    psLibFinalize();
+
+    return 0;
+}
+
+static psS32 testCellAlloc(void)
+{
+    char* name = "The Kaiser Royal Observatory";
+
+    psTime* now = psTimeGetTime(PS_TIME_TAI);
+
+    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 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of readouts properly.");
+        return 2;
+    }
+
+    if (cell1->readouts->nalloc != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not allocat the readout array properly.");
+        return 2;
+    }
+
+    for (psS32 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.
+    }
+    cell1->readouts->n = 8;
+
+    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 one.
+    */
+
+    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->readouts->nalloc != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not allocate the readout array properly.");
+        return 13;
+    }
+
+    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 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of cells properly.");
+        return 22;
+    }
+
+    if (cell3->readouts->nalloc != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of cells properly.");
+        return 23;
+    }
+
+    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);
+    psLibFinalize();
+
+    return 0;
+}
+
+static psS32 testReadoutAlloc(void)
+{
+    psReadout* readout = psReadoutAlloc();
+
+    if (readout == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psReadoutAlloc returned NULL.");
+        return 1;
+    }
+
+    if (readout->col0 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set col0 properly.");
+        return 2;
+    }
+
+    if (readout->row0 != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set row0 properly.");
+        return 3;
+    }
+
+    if (readout->image != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set the image properly.");
+        return 4;
+    }
+
+    readout->image = psAlloc(4); // to check if these are freed.
+
+    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/rel4/psLib/test/astronomy/tst_psAstrometry01.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psAstrometry01.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psAstrometry01.c	(revision 3057)
@@ -0,0 +1,539 @@
+/** @file  tst_psAstrometry01.c
+*
+*  @brief The code in this file will test the code in psAstrometry.[ch]
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-14 01:13:15 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 test1( void );
+static psS32 test2( void );
+static psS32 test3( void );
+
+testDescription tests[] = {
+                              {test1, -1, "Tests psFixedPatternAlloc()", 0, false},
+                              {test2, -2, "Tests psGrommitAlloc()", 0, false},
+                              {test3, -3, "MISC", 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()
+{
+    psS32 i;
+    psS32 j;
+    psS32 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;
+    myFPA->chips->n = NUM_CHIPS;
+
+    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;
+        chips[i]->cells->n = NUM_CELLS;
+
+        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;
+            cells[j]->readouts->n = NUM_READOUTS;
+
+            for (k=0;k<NUM_READOUTS;k++) {
+                tmpImage = psImageAlloc(READOUT_NUM_COLS, READOUT_NUM_ROWS, PS_TYPE_F32);
+                for (psS32 row=0;row<READOUT_NUM_ROWS;row++) {
+                    for(psS32 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();
+                readouts[k]->image = tmpImage;
+                *(psS32*)&readouts[k]->col0 = (j * (CELL_WIDTH + CELL_GAP));
+                *(psS32*)&readouts[k]->row0 = 0;
+
+
+            }
+        }
+    }
+
+    return(myFPA);
+}
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psAstrometry", 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
+
+psS32 test1( void )
+{
+    psS32 i;
+    psS32 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);
+    psS32 testStatus = 0;
+    psS32 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;
+}
+
+psS32 test2()
+{
+    psS32 testStatus = 0;
+
+    psTime* now = psTimeGetTime(PS_TIME_TAI);
+
+    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);
+    psLibFinalize();
+
+    return(testStatus);
+}
+
+psS32 printCell(psCell *cell)
+{
+    psReadout **readouts = (psReadout **) cell->readouts->data;
+    psReadout *readout = readouts[0];
+
+    printf("-------------------------------\n");
+    for (psS32 i = 0; i < readout->image->numRows ; i++) {
+        for (psS32 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.
+ 
+ 
+ *****************************************************************************/
+psS32 test3( void )
+{
+    psS32 x;
+    psS32 y;
+    psPlane fpaCoord;
+    psFPA *myFPA = genSystem();
+    psCell *myCell = NULL;
+    psPlane chipCoord;
+    psPlane cellCoord;
+    psPlane testCoord;
+
+    psS32 xReadout = 0;
+    psS32 xFPA = 0;
+    for (psS32 chip=0;chip<NUM_CHIPS;chip++) {
+        for (psS32 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)) {
+                        if (myCell == NULL) {
+                            printf("ERROR: myCell is NULL\n");
+                        }
+                        if (tmpChip == NULL) {
+                            printf("ERROR: tmpChip is NULL\n");
+                        }
+                    } else {
+                        psCoordFPAToChip(&chipCoord, &fpaCoord, tmpChip);
+                        psCoordChipToCell(&cellCoord, &chipCoord, myCell);
+
+                        if (x != (psS32) cellCoord.x) {
+                            printf("ERROR: x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (y != (psS32) 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;
+        }
+    }
+
+    printf("HERE 00\n");
+    psFree(myFPA);
+    printf("HERE 01\n");
+
+    return(0);
+}
+//This code is
Index: /branches/rel4/psLib/test/astronomy/tst_psCoord.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psCoord.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psCoord.c	(revision 3057)
@@ -0,0 +1,1310 @@
+/** @file  tst_psCoord.c
+*
+*  @brief The code will ...
+*
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-14 23:25:39 $
+*
+*  XXX: Must test psSpherePrecess.
+*  XXX: THe psProject() and psDeproject() functions do not work fully.  They
+*  are not tested here.  The SphereGet/SetOffset() code that rely on them
+*  is not tested.
+*
+*  XXX: Test with a bad offfset unit type in the SphereGet/SetOffset() functions.
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+static psS32 test1( void );
+static psS32 test1b( void );
+static psS32 test1c( void );
+static psS32 test2( void );
+static psS32 test3( void );
+static psS32 test4( void );
+static psS32 test4b( void );
+static psS32 test5( void );
+static psS32 test6( void );
+static psS32 test7( void );
+static psS32 test8( void );
+//static psS32 test20( void );
+//static psS32 test21( void );
+static psS32 test40( void );
+static psS32 test41( void );
+//static psS32 test42( void );
+//static psS32 test43( void );
+testDescription tests[] = {
+                              {test1, 0000, "psSphereTransformAlloc()", 0, false},
+                              {test1b, 0000, "psPlaneTransformAlloc()", 0, false},
+                              {test1c, 0000, "psPlaneDistortAlloc()", 0, false},
+                              {test2, 0000, "psPlaneTransformApply()", 0, false},
+                              {test3, 0000, "psPlaneDistortApply()", 0, false},
+                              {test4, 0000, "psPSphereTransformApply()", 0, false},
+                              {test4b, 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},
+                              //         {test42, 0000, "psProject(), psDeproject", 0, false},
+                              //         {test43, 0000, "psProject(), psDeproject", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psCoord", 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 (testStatus = %d)\n", #ACTUAL, ACTUAL, EXPECT, TESTSTATUS); \
+    testStatus = TESTSTATUS; \
+}
+#define MY_TINY 0.0001
+#define PS_COMPARE_EPSILON_THEN_PRINT_ERROR(ACTUAL, EXPECT, TESTSTATUS) \
+if (FLT_EPSILON < fabs(EXPECT - ACTUAL)) { \
+    printf("ERROR: %s is %f, should be %f (testStatus = %d)\n", #ACTUAL, ACTUAL, EXPECT, TESTSTATUS); \
+    testStatus = TESTSTATUS; \
+}
+
+#define PS_COT(X) (1.0 / atan(X))
+float p_psArg(float x,
+              float y)
+{
+    return((float) atan2((double) x, (double) y));
+}
+
+#define ALPHA_P 1.0
+#define DELTA_P 2.0
+#define PHI_P 3.0
+psS32 test1( void )
+{
+    psS32 testStatus = 0;
+    psSphereTransform *myST = psSphereTransformAlloc(ALPHA_P, DELTA_P, PHI_P);
+
+    psF32 sinDeltaP = sin(DELTA_P);
+    if (FLT_EPSILON < fabs(sinDeltaP - myST->sinDeltaP)) {
+        printf("ERROR: myST->sinDeltaP is %f, should be %f\n", myST->sinDeltaP, sinDeltaP);
+        testStatus = 1;
+    }
+    psF32 cosDeltaP = cos(DELTA_P);
+    if (FLT_EPSILON < fabs(cosDeltaP - myST->cosDeltaP)) {
+        printf("ERROR: myST->cosDeltaP is %f, should be %f\n", myST->cosDeltaP, cosDeltaP);
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(ALPHA_P - myST->alphaP)) {
+        printf("ERROR: myST->alphaP is %f, should be %f\n", myST->alphaP, ALPHA_P);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(PHI_P - myST->phiP)) {
+        printf("ERROR: myST->phiP is %f, should be %f\n", myST->phiP, PHI_P);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+#define NW_TERMS 2
+#define NX_TERMS 3
+#define NY_TERMS 4
+#define NZ_TERMS 5
+psS32 test1b( void )
+{
+    psS32 testStatus = 0;
+    psPlaneTransform *myPT = psPlaneTransformAlloc(NX_TERMS, NY_TERMS);
+
+    if (myPT->x->nX != NX_TERMS) {
+        printf("ERROR: myPT->x->nX is %d, should be %d\n", myPT->x->nX, NX_TERMS);
+        testStatus = 1;
+    }
+    if (myPT->y->nX != NX_TERMS) {
+        printf("ERROR: myPT->y->nX is %d, should be %d\n", myPT->y->nX, NX_TERMS);
+        testStatus = 1;
+    }
+
+    if (myPT->x->nY != NY_TERMS) {
+        printf("ERROR: myPT->x->nY is %d, should be %d\n", myPT->x->nY, NY_TERMS);
+        testStatus = 1;
+    }
+    if (myPT->y->nY != NY_TERMS) {
+        printf("ERROR: myPT->y->nY is %d, should be %d\n", myPT->y->nY, NY_TERMS);
+        testStatus = 1;
+    }
+    psFree(myPT);
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPT = psPlaneTransformAlloc(-1.0, 1.0);
+    if (myPT != NULL) {
+        printf("TEST ERROR: psPlaneTransformAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPT = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPT = psPlaneTransformAlloc(1.0, -1.0);
+    if (myPT != NULL) {
+        printf("TEST ERROR: psPlaneTransformAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPT = NULL;
+    }
+    printf("-------------------------------------------------------------------\n");
+
+
+    psFree(myPT);
+    return(testStatus);
+}
+psS32 test1c( void )
+{
+    psS32 testStatus = 0;
+    psPlaneDistort *myPD = psPlaneDistortAlloc(NW_TERMS, NX_TERMS, NY_TERMS, NZ_TERMS);
+
+    if (myPD->x->nW != NW_TERMS) {
+        printf("ERROR: myPD->x->nW is %d, should be %d\n", myPD->x->nW, NW_TERMS);
+        testStatus = 1;
+    }
+    if (myPD->y->nW != NW_TERMS) {
+        printf("ERROR: myPD->y->nW is %d, should be %d\n", myPD->y->nW, NW_TERMS);
+        testStatus = 1;
+    }
+
+    if (myPD->x->nX != NX_TERMS) {
+        printf("ERROR: myPD->x->nX is %d, should be %d\n", myPD->x->nX, NX_TERMS);
+        testStatus = 1;
+    }
+    if (myPD->y->nX != NX_TERMS) {
+        printf("ERROR: myPD->y->nX is %d, should be %d\n", myPD->y->nX, NX_TERMS);
+        testStatus = 1;
+    }
+
+    if (myPD->x->nY != NY_TERMS) {
+        printf("ERROR: myPD->x->nY is %d, should be %d\n", myPD->x->nY, NY_TERMS);
+        testStatus = 1;
+    }
+    if (myPD->y->nY != NY_TERMS) {
+        printf("ERROR: myPD->y->nY is %d, should be %d\n", myPD->y->nY, NY_TERMS);
+        testStatus = 1;
+    }
+
+    if (myPD->x->nZ != NZ_TERMS) {
+        printf("ERROR: myPD->x->nZ is %d, should be %d\n", myPD->x->nZ, NZ_TERMS);
+        testStatus = 1;
+    }
+    if (myPD->y->nZ != NZ_TERMS) {
+        printf("ERROR: myPD->y->nZ is %d, should be %d\n", myPD->y->nZ, NZ_TERMS);
+        testStatus = 1;
+    }
+
+    psFree(myPD);
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPD = psPlaneDistortAlloc(-1.0, 1.0, 1.0, 1.0);
+    if (myPD != NULL) {
+        printf("TEST ERROR: psPlaneDistortAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPD = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPD = psPlaneDistortAlloc(1.0, -1.0, 1.0, 1.0);
+    if (myPD != NULL) {
+        printf("TEST ERROR: psPlaneDistortAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPD = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPD = psPlaneDistortAlloc(1.0, 1.0, -1.0, 1.0);
+    if (myPD != NULL) {
+        printf("TEST ERROR: psPlaneDistortAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPD = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.\n");
+    myPD = psPlaneDistortAlloc(1.0, 1.0, 1.0, -1.0);
+    if (myPD != NULL) {
+        printf("TEST ERROR: psPlaneDistortAlloc() did not return NULL.\n");
+        testStatus = false;
+        myPD = NULL;
+    }
+    printf("-------------------------------------------------------------------\n");
+
+    return(testStatus);
+}
+
+#define N 10
+// We do a simple identity transformation on a few x,y pairs.
+psS32 test2( void )
+{
+    psS32 i;
+    psS32 testStatus = 0;
+    psPlane in;
+    psPlane out;
+    psPlane *rc;
+    psPlaneTransform pt;
+    psDPolynomial2D *tmp2DPoly = NULL;
+
+    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);
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformApply() with NULL psPlaneTransform.  Should generate error, return NULL.\n");
+    rc = psPlaneTransformApply(NULL, NULL, &in);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformApply() with NULL psPlaneTransform->x.  Should generate error, return NULL.\n");
+    tmp2DPoly = pt.x;
+    pt.x = NULL;
+    rc = psPlaneTransformApply(NULL, &pt, &in);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+    pt.x = tmp2DPoly;
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformApply() with NULL psPlaneTransform->y.  Should generate error, return NULL.\n");
+    tmp2DPoly = pt.y;
+    pt.y = NULL;
+    rc = psPlaneTransformApply(NULL, &pt, &in);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+    pt.y = tmp2DPoly;
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneTransformApply() with NULL input coords.  Should generate error, return NULL.\n");
+    rc = psPlaneTransformApply(NULL, &pt, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    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.
+psS32 test3( void )
+{
+    psS32 i;
+    psS32 testStatus = 0;
+    psPlane in;
+    psPlane out;
+    psPlaneDistort pt;
+    psPlane *rc = NULL;
+    psDPolynomial4D *tmp4DPoly = NULL;
+
+    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);
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortApply() with NULL psPlaneDistort.  Should generate error, return NULL.\n");
+    rc = psPlaneDistortApply(NULL, NULL, &in, COLOR, MAGNITUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneDistortApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortApply() with NULL psPlaneDistort->x.  Should generate error, return NULL.\n");
+    tmp4DPoly = pt.x;
+    pt.x = NULL;
+    rc = psPlaneDistortApply(NULL, &pt, &in, COLOR, MAGNITUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneDistortApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+    pt.x = tmp4DPoly;
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortApply() with NULL psPlaneDistort->y.  Should generate error, return NULL.\n");
+    tmp4DPoly = pt.y;
+    pt.y = NULL;
+    rc = psPlaneDistortApply(NULL, &pt, &in, COLOR, MAGNITUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneDistortApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+    pt.y = tmp4DPoly;
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psPlaneDistortApply() with NULL input coords.  Should generate error, return NULL.\n");
+    rc = psPlaneDistortApply(NULL, &pt, NULL, COLOR, MAGNITUDE);
+    if (rc != NULL) {
+        printf("TEST ERROR: psPlaneDistortApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+
+
+    printf("-------------------------------------------------------------------\n");
+    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.
+psS32 test4( void )
+{
+    psS32 testStatus = 0;
+    psSphere in;
+    psSphere out;
+    psSphere *rc = NULL;
+    psSphereTransform *myST = psSphereTransformAlloc(0.0, 0.0, 0.0);
+
+    in.r = DEG_TO_RAD(45.0);
+    in.d = DEG_TO_RAD(30.0);
+    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 = DEG_TO_RAD(r);
+            in.d = DEG_TO_RAD(d);
+            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);
+        }
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereTransformApply() with NULL psSphereTransform.  Should generate error, return NULL.\n");
+    rc = psSphereTransformApply(NULL, NULL, &in);
+    if (rc != NULL) {
+        printf("TEST ERROR: psSphereTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereTransformApply() with NULL input coords.  Should generate error, return NULL.\n");
+    rc = psSphereTransformApply(NULL, myST, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: psSphereTransformApply() did not return NULL.\n");
+        testStatus = false;
+        rc = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    psFree(myST);
+    return(testStatus);
+}
+
+/******************************************************************************
+test4b(): This test verifies that psSphereTransformApply() works properly.  We
+create two psSphereTransforms: a forward transform and a reverse transform
+(which is the mathematical inverse of the forward transform).  We apply both
+transforms to several spherical coordinates and ensure that the original input
+coordinate is obtained after applying both transforms.
+ 
+XXX: We currently test the alpha and delta offsets independently.  Attempts to
+test them both concurrently failed.  Determine why this is.  Are the following
+spherical transforms not mathematical inverses?
+    psSphereTransformAlloc(X, Y, 0.0)
+    psSphereTransformAlloc(-X, -Y, 0.0)
+ *****************************************************************************/
+#define ERROR_PERCENT 0.01
+psS32 test4b( void )
+{
+    psS32 testStatus = 0;
+    psSphere in;
+    psSphere out;
+    psSphere out2;
+    psSphereTransform *mySphereTransformForward = NULL;
+    psSphereTransform *mySphereTransformReverse = NULL;
+
+
+    mySphereTransformForward = psSphereTransformAlloc(DEG_TO_RAD(22.0),
+                               0.0,
+                               0.0);
+    mySphereTransformReverse = psSphereTransformAlloc(DEG_TO_RAD(-22.0),
+                               0.0,
+                               0.0);
+
+    for (float r=0.1;r<180.0;r+=(DEG_INC/5.0)) {
+        for (float d=0.1;d<90.0;d+=(DEG_INC/5.0)) {
+            in.r = DEG_TO_RAD(r);
+            in.d = DEG_TO_RAD(d);
+            in.rErr = 0.0;
+            in.dErr = 0.0;
+
+            psSphereTransformApply(&out, mySphereTransformForward, &in);
+            psSphereTransformApply(&out2, mySphereTransformReverse, &out);
+
+            if ((fabs((in.r - out2.r) / in.r) > ERROR_PERCENT) ||
+                    (fabs((in.d - out2.d) / in.d) > ERROR_PERCENT)) {
+                printf("ERROR: \n");
+                printf("Input  coords (R, D) are (%f, %f)\n", in.r, in.d);
+                printf("Output coords (R, D) are (%f, %f)\n", out2.r, out2.d);
+                testStatus = 4;
+            }
+        }
+    }
+    psFree(mySphereTransformForward);
+    psFree(mySphereTransformReverse);
+
+    mySphereTransformForward = psSphereTransformAlloc(0.0,
+                               DEG_TO_RAD(33.0),
+                               0.0);
+    mySphereTransformReverse = psSphereTransformAlloc(0.0,
+                               DEG_TO_RAD(-33.0),
+                               0.0);
+    for (float r=0.1;r<180.0;r+=(DEG_INC/5.0)) {
+        for (float d=0.1;d<90.0;d+=(DEG_INC/5.0)) {
+            in.r = DEG_TO_RAD(r);
+            in.d = DEG_TO_RAD(d);
+            in.rErr = 0.0;
+            in.dErr = 0.0;
+
+            psSphereTransformApply(&out, mySphereTransformForward, &in);
+            psSphereTransformApply(&out2, mySphereTransformReverse, &out);
+
+            if ((fabs((in.r - out2.r) / in.r) > ERROR_PERCENT) ||
+                    (fabs((in.d - out2.d) / in.d) > ERROR_PERCENT)) {
+                printf("ERROR: \n");
+                printf("Input  coords (R, D) are (%f, %f)\n", in.r, in.d);
+                printf("Output coords (R, D) are (%f, %f)\n", out2.r, out2.d);
+                testStatus = 4;
+            }
+        }
+    }
+    psFree(mySphereTransformForward);
+    psFree(mySphereTransformReverse);
+
+    return(testStatus);
+}
+
+psS32 test5( void )
+{
+    psS32 testStatus = 0;
+
+    // XXX: This test code is simply a copy of the original source code.
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    struct tm *tm_time = psTimeToTM(now);
+    psF64 MJD = psTimeToMJD(now);
+    struct tm *tmTime = psTimeToTM(now);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 expectedAlphaP = 0.0;
+    psF64 expectedDeltaP = DEG_TO_RAD(23.0) +
+                           SEC_TO_RAD(27.0) +
+                           MIN_TO_RAD(8.0) -
+                           (SEC_TO_RAD(46.845) * T) -
+                           (SEC_TO_RAD(0.0059) * T * T) +
+                           (SEC_TO_RAD(0.00181) * T * T * T);
+    expectedDeltaP*= -1.0;
+    psF64 expectedPhiP = 0.0;
+    psFree(tmTime);
+
+    psSphereTransform *myST = psSphereTransformICRSToEcliptic(now);
+
+    if (FLT_EPSILON < fabs(sin(expectedDeltaP) - myST->sinDeltaP)) {
+        printf("ERROR: myST->sinDeltaP is %f, should be %f\n", myST->sinDeltaP, sin(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(expectedDeltaP) - myST->cosDeltaP)) {
+        printf("ERROR: myST->cosDeltaP is %f, should be %f\n", myST->cosDeltaP, cos(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(expectedAlphaP - myST->alphaP)) {
+        printf("ERROR: myST->alphaP is %f, should be %f\n", myST->alphaP, expectedAlphaP);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(expectedPhiP - myST->phiP)) {
+        printf("ERROR: myST->phiP is %f, should be %f\n", myST->phiP, expectedPhiP);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    psFree(tm_time);
+    psFree(now);
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereTransformICRSToEcliptic() with NULL input.  Should generate error, return NULL.\n");
+    myST = psSphereTransformICRSToEcliptic(NULL);
+    if (myST != NULL) {
+        printf("TEST ERROR: psSphereTransformApply() did not return NULL.\n");
+        testStatus = false;
+        myST = NULL;
+    }
+
+    return(testStatus);
+}
+
+
+psS32 test6( void )
+{
+    psS32 testStatus = 0;
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    struct tm *tm_time = psTimeToTM(now);
+    psF64 MJD = psTimeToMJD(now);
+    struct tm *tmTime = psTimeToTM(now);
+    psF64 year = (psF64)(1900 - MJD + tmTime->tm_year);
+    psF64 T = year / 100.0;
+    psF64 expectedAlphaP = 0.0;
+    psF64 expectedDeltaP = DEG_TO_RAD(23.0) +
+                           SEC_TO_RAD(27.0) +
+                           MIN_TO_RAD(8.0) -
+                           (SEC_TO_RAD(46.845) * T) -
+                           (SEC_TO_RAD(0.0059) * T * T) +
+                           (SEC_TO_RAD(0.00181) * T * T * T);
+    psF64 expectedPhiP = 0.0;
+    psSphereTransform *myST = psSphereTransformEclipticToICRS(now);
+
+    if (FLT_EPSILON < fabs(sin(expectedDeltaP) - myST->sinDeltaP)) {
+        printf("ERROR: myST->sinDeltaP is %f, should be %f\n", myST->sinDeltaP, sin(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(expectedDeltaP) - myST->cosDeltaP)) {
+        printf("ERROR: myST->cosDeltaP is %f, should be %f\n", myST->cosDeltaP, cos(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(expectedAlphaP - myST->alphaP)) {
+        printf("ERROR: myST->alphaP is %f, should be %f\n", myST->alphaP, expectedAlphaP);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(expectedPhiP - myST->phiP)) {
+        printf("ERROR: myST->phiP is %f, should be %f\n", myST->phiP, expectedPhiP);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    psFree(tm_time);
+    psFree(tmTime);
+    psFree(now);
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereTransformEclipticToICRS() with NULL input.  Should generate error, return NULL.\n");
+    myST = psSphereTransformEclipticToICRS(NULL);
+    if (myST != NULL) {
+        printf("TEST ERROR: psSphereTransformApply() did not return NULL.\n");
+        testStatus = false;
+        myST = NULL;
+    }
+
+    return(testStatus);
+}
+
+psS32 test7( void )
+{
+    psS32 testStatus = 0;
+    // XXX: This test code is simply a copy of the original source code.
+    psF64 expectedAlphaP = DEG_TO_RAD(32.93192);
+    psF64 expectedDeltaP = DEG_TO_RAD(-62.87175);
+    psF64 expectedPhiP = DEG_TO_RAD(282.85948);
+    psSphereTransform *myST = psSphereTransformICRSToGalatic();
+
+    if (FLT_EPSILON < fabs(sin(expectedDeltaP) - myST->sinDeltaP)) {
+        printf("ERROR: myST->sinDeltaP is %f, should be %f\n", myST->sinDeltaP, sin(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(expectedDeltaP) - myST->cosDeltaP)) {
+        printf("ERROR: myST->cosDeltaP is %f, should be %f\n", myST->cosDeltaP, cos(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(expectedAlphaP - myST->alphaP)) {
+        printf("ERROR: myST->alphaP is %f, should be %f\n", myST->alphaP, expectedAlphaP);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(expectedPhiP - myST->phiP)) {
+        printf("ERROR: myST->phiP is %f, should be %f\n", myST->phiP, expectedPhiP);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+psS32 test8( void )
+{
+    psS32 testStatus = 0;
+    // XXX: This test code is simply a copy of the original source code.
+    psF64 expectedAlphaP = DEG_TO_RAD(282.85948);
+    psF64 expectedDeltaP = DEG_TO_RAD(62.87175);
+    psF64 expectedPhiP = DEG_TO_RAD(32.93192);
+    psSphereTransform *myST = psSphereTransformGalaticToICRS();
+
+    if (FLT_EPSILON < fabs(sin(expectedDeltaP) - myST->sinDeltaP)) {
+        printf("ERROR: myST->sinDeltaP is %f, should be %f\n", myST->sinDeltaP, sin(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(expectedDeltaP) - myST->cosDeltaP)) {
+        printf("ERROR: myST->cosDeltaP is %f, should be %f\n", myST->cosDeltaP, cos(expectedDeltaP));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(expectedAlphaP - myST->alphaP)) {
+        printf("ERROR: myST->alphaP is %f, should be %f\n", myST->alphaP, expectedAlphaP);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(expectedPhiP - myST->phiP)) {
+        printf("ERROR: myST->phiP is %f, should be %f\n", myST->phiP, expectedPhiP);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+psS32 test20( void )
+{
+    psS32 testStatus = 0;
+    psSphere in;
+    double expectX;
+    double expectY;
+    psPlane *out;
+    psProjection myProjection;
+    myProjection.R = DEG_TO_RAD(20.0);
+    myProjection.D = DEG_TO_RAD(10.0);
+    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 = DEG_TO_RAD(r);
+            in.d = DEG_TO_RAD(d);
+            in.rErr = 0.0;
+            in.dErr = 0.0;
+
+            /******************************************************************
+             Tangent Plane Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_TAN;
+            out = psProject(&in, &myProjection);
+            expectX = cos(in.r) * sin(in.d) / sin(in.r);
+            expectY = -cos(in.r) * cos(in.d) / sin(in.r);
+            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);
+            expectX = cos(in.d) * sin(in.d);
+            expectY = -cos(in.d) * 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(DEG_TO_RAD(45.0) + (0.5 * in.r)));
+
+            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);
+
+
+            psF64 tmpF64  = PS_SQRT_F32(0.5 * (1.0 + (cos(in.r) * cos(0.5 * in.d))));
+            tmpF64 = 1.0 / tmpF64;
+            expectX = 2.0 * tmpF64 * cos(in.r) * sin(0.5 * in.d);
+            expectY = sin(in.r) * tmpF64;
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 20);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 21);
+            psFree(out);
+
+
+        }
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psProject() with NULL input coords.  Should generate error, return NULL.\n");
+    out = psProject(NULL, &myProjection);
+    if (out != NULL) {
+        printf("TEST ERROR: psSphereTransformEclipticToICRS() did not return NULL.\n");
+        testStatus = false;
+        out = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psProject() with NULL psProjection.  Should generate error, return NULL.\n");
+    out = psProject(&in, NULL);
+    if (out != NULL) {
+        printf("TEST ERROR: psProject() did not return NULL.\n");
+        testStatus = false;
+        out = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+
+    return(testStatus);
+}
+
+#define SPACE_INC 10.0
+psS32 test21( void )
+{
+    psS32 testStatus = 0;
+    psPlane in;
+    double R;
+    double expectD;
+    double expectR;
+    psSphere *out;
+    psProjection myProjection;
+    myProjection.R = DEG_TO_RAD(20.0);
+    myProjection.D = DEG_TO_RAD(10.0);
+    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 = PS_SQRT_F32((in.x * in.x) + (in.y * in.y));
+            expectD = atan(1.0 / R);
+            expectR = atan2(-in.y, in.x);
+
+            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);
+        }
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psDeproject() with NULL input coords.  Should generate error, return NULL.\n");
+    out = psDeproject(NULL, &myProjection);
+    if (out != NULL) {
+        printf("TEST ERROR: psDeproject() did not return NULL.\n");
+        testStatus = false;
+        out = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psDeproject() with NULL psProjection.  Should generate error, return NULL.\n");
+    out = psDeproject(&in, NULL);
+    if (out != NULL) {
+        printf("TEST ERROR: psDeproject() did not return NULL.\n");
+        testStatus = false;
+        out = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+
+    return(testStatus);
+}
+
+psS32 test40( void )
+{
+    psS32 testStatus = 0;
+    psSphere position1;
+    psSphere position2;
+    psSphere *offset = NULL;
+
+    position1.r = DEG_TO_RAD(90.0);
+    position1.d = DEG_TO_RAD(45.0);
+    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 = DEG_TO_RAD(r);
+            position2.d = DEG_TO_RAD(d);
+            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 = DEG_TO_RAD(offset->r);
+            offset->d = DEG_TO_RAD(offset->d);
+            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 = MIN_TO_RAD(offset->r);
+            offset->d = MIN_TO_RAD(offset->d);
+            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 = SEC_TO_RAD(offset->r);
+            offset->d = SEC_TO_RAD(offset->d);
+            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);
+
+            //HEY            /* XXX: This code does not work correctly.
+            //            printf("--------------- (%f, %f) to (%f, %f) is (%f, %f) ---------------\n",
+            //                   position1.r, position1.d, position2.r, position2.d,
+            //                   offset->r, offset->d);
+            //            offset = psSphereGetOffset(&position1, &position2, PS_LINEAR, 0);
+            //            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);
+        }
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereGetOffset() with NULL position1.  Should generate error, return NULL.\n");
+    offset = psSphereGetOffset(NULL, &position2, PS_LINEAR, 0);
+    if (offset != NULL) {
+        printf("TEST ERROR: psSphereGetOffset() did not return NULL.\n");
+        testStatus = false;
+        offset = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereGetOffset() with NULL position2.  Should generate error, return NULL.\n");
+    offset = psSphereGetOffset(&position1, NULL, PS_LINEAR, 0);
+    if (offset != NULL) {
+        printf("TEST ERROR: psSphereGetOffset() did not return NULL.\n");
+        testStatus = false;
+        offset = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereGetOffset() with bogus offset mode.  Should generate error, return NULL.\n");
+    offset = psSphereGetOffset(&position1, &position2, 0x54321, 0);
+    if (offset != NULL) {
+        printf("TEST ERROR: psSphereGetOffset() did not return NULL.\n");
+        testStatus = false;
+        offset = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereGetOffset() with bogus offset units.  Should generate error, return NULL.\n");
+    offset = psSphereGetOffset(&position1, &position2, PS_SPHERICAL, 0x54321);
+    if (offset != NULL) {
+        printf("TEST ERROR: psSphereGetOffset() did not return NULL.\n");
+        testStatus = false;
+        offset = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    return(testStatus);
+}
+
+psS32 test41( void )
+{
+    psS32 testStatus = 0;
+    psSphere position1;
+    psSphere *position2;
+    psSphere offset;
+    psSphere tmpOffset;
+
+    position1.r = DEG_TO_RAD(90.0);
+    position1.d = DEG_TO_RAD(45.0);
+    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 = DEG_TO_RAD(r);
+            offset.d = DEG_TO_RAD(d);
+            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), 2);
+            psFree(position2);
+
+            tmpOffset.r = RAD_TO_DEG(offset.r);
+            tmpOffset.d = RAD_TO_DEG(offset.d);
+            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), 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 4);
+            psFree(position2);
+
+            tmpOffset.r = RAD_TO_MIN(offset.r);
+            tmpOffset.d = RAD_TO_MIN(offset.d);
+            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), 5);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 6);
+            psFree(position2);
+
+            tmpOffset.r = RAD_TO_SEC(offset.r);
+            tmpOffset.d = RAD_TO_SEC(offset.d);
+            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), 7);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 8);
+            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);
+            */
+        }
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereSetOffset() with NULL position1.  Should generate error, return NULL.\n");
+    position2 = psSphereSetOffset(NULL, &offset, PS_LINEAR, 0);
+    if (position2 != NULL) {
+        printf("TEST ERROR: psSphereSetOffset() did not return NULL.\n");
+        testStatus = false;
+        position2 = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereSetOffset() with NULL offset.  Should generate error, return NULL.\n");
+    position2 = psSphereSetOffset(&position1, NULL, PS_LINEAR, 0);
+    if (position2 != NULL) {
+        printf("TEST ERROR: psSphereSetOffset() did not return NULL.\n");
+        testStatus = false;
+        position2 = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereSetOffset() with bogus offset mode.  Should generate error, return NULL.\n");
+    position2 = psSphereSetOffset(&position1, &offset, 0x54321, 0);
+    if (position2 != NULL) {
+        printf("TEST ERROR: psSphereSetOffset() did not return NULL.\n");
+        testStatus = false;
+        position2 = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    printf("Calling psSphereSetOffset() with bogus offset unit.  Should generate error, return NULL.\n");
+    position2 = psSphereSetOffset(&position1, &offset, PS_SPHERICAL, 0x54321);
+    if (position2 != NULL) {
+        printf("TEST ERROR: psSphereSetOffset() did not return NULL.\n");
+        testStatus = false;
+        position2 = NULL;
+    }
+
+    printf("-------------------------------------------------------------------\n");
+    return(testStatus);
+}
+
+/******************************************************************************
+test43(): Not really a test.  We simply project many points and print the
+results.
+ *****************************************************************************/
+psS32 test43( void )
+{
+    psS32 testStatus = 0;
+    psSphere projCenter;
+    psSphere startCoords;
+    psPlane *planeCoords;
+
+    projCenter.r = DEG_TO_RAD(33.0);
+    projCenter.d = DEG_TO_RAD(22.0);
+    projCenter.r = 0.0;
+    projCenter.d = 0.0;
+    // Create the psProjection plane:
+    psProjection myProj;
+    myProj.R = projCenter.r;
+    myProj.D = projCenter.d;
+    myProj.Xs = 1.0;
+    myProj.Ys = 1.0;
+    myProj.type = PS_PROJ_TAN;
+
+    printf("    projCenter is (%f, %f)\n", projCenter.r, projCenter.d);
+    for (float r=-90.0;r<90.0;r+=DEG_INC/5.0) {
+        for (float d=-90.0;d<90.0;d+=DEG_INC/5.0) {
+            printf("----------------------------------------------------------\n");
+            printf("Angles (R, D) are (%.2f, %.2f)\n", r, d);
+            startCoords.r = DEG_TO_RAD(r);
+            startCoords.d = DEG_TO_RAD(d);
+
+            planeCoords = psProject(&startCoords, &myProj);
+            printf("    startCoords (R, D) is (%f, %f)\n", startCoords.r, startCoords.d);
+            printf("        plane Coords (X, Y) is (%f, %f)\n", planeCoords->x, planeCoords->y);
+            psFree(planeCoords);
+        }
+    }
+    printf("----------------------------------------------------------\n");
+    return(testStatus);
+}
+
+bool testNonEqualF32(psF32 num1, psF32 num2)
+{
+    if ((fabs(num1) <= FLT_EPSILON) && (fabs(num2) <= FLT_EPSILON)) {
+        return(false);
+    }
+
+    if (fabs((num2 - num1) / num1) <= ERROR_PERCENT) {
+        return(false);
+    }
+    return(true);
+}
+
+#define NUM_DEGREES 5
+/******************************************************************************
+test42(): This test attempts to verify the psProject() and psDeproject()
+functions.  We create an arbitrary psProjection.  We then project several
+spherical coordinates onto the plane and then immediately deproject them; we
+ensure that the resulting spherical coordinates are identical to the start
+coordinates.
+ 
+Currently, this test works only for angles near the first quadrant.
+ *****************************************************************************/
+psS32 test42( void )
+{
+    psS32 testStatus = 0;
+    psSphere projCenter;
+    psSphere startCoords;
+    psSphere *endCoords;
+    psPlane *planeCoords;
+
+    #define PROG_CENTER_R_DEG 15.0
+    #define PROG_CENTER_D_DEG 20.0
+
+    projCenter.r = DEG_TO_RAD(PROG_CENTER_R_DEG);
+    projCenter.d = DEG_TO_RAD(PROG_CENTER_D_DEG);
+    // Create the psProjection plane:
+    psProjection myProj;
+    myProj.R = projCenter.r;
+    myProj.D = projCenter.d;
+    myProj.Xs = 1.0;
+    myProj.Ys = 1.0;
+    myProj.type = PS_PROJ_TAN;
+
+    #define RADIUS_DEG 30.0
+    #define NUM_ANGLES 30
+    #define MY_DEG_INC ((2.0 * RADIUS_DEG) / NUM_ANGLES)
+
+    for (float r= (PROG_CENTER_R_DEG - RADIUS_DEG);
+            r<=(PROG_CENTER_R_DEG + RADIUS_DEG);
+            r+=MY_DEG_INC) {
+        printf("------------------------ r is %.1f ------------------------\n", r);
+        for (float d= (PROG_CENTER_D_DEG - RADIUS_DEG);
+                d<=(PROG_CENTER_D_DEG + RADIUS_DEG);
+                d+=MY_DEG_INC) {
+            startCoords.r = DEG_TO_RAD(r);
+            startCoords.d = DEG_TO_RAD(d);
+            printf("----- startCoords (R, D) is (%f, %f) is deg (%.1f, %.1f)  -----\n", startCoords.r, startCoords.d, r, d);
+
+            planeCoords = psProject(&startCoords, &myProj);
+            endCoords = psDeproject(planeCoords, &myProj);
+
+            if (testNonEqualF32(endCoords->r, startCoords.r) ||
+                    testNonEqualF32(endCoords->d, startCoords.d)) {
+                printf("ERROR: \n");
+                printf("    startCoords (R, D) is (%f, %f)\n", startCoords.r, startCoords.d);
+                //                printf("        plane Coords is (%f, %f)\n", planeCoords->x, planeCoords->y);
+                printf("    endCoords (R, D) is (%f, %f)\n", endCoords->r, endCoords->d);
+            }
+            psFree(planeCoords);
+            psFree(endCoords);
+        }
+    }
+    return(testStatus);
+}
+
+// This code will ...
+
Index: /branches/rel4/psLib/test/astronomy/tst_psMetadataIO.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadataIO.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadataIO.c	(revision 3057)
@@ -0,0 +1,171 @@
+/** @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.6 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 02:50:15 $
+*
+*  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 printMetadata(psMetadata *metadata);
+static void printMetadataList(psList *metadataItemList, char* spaces);
+static void printMetadataTable(psHash *mdTable);
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list, " ");
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+static void printMetadataList(psList *metadataItemList, char* spaces)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListIterator* iter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD);
+
+    while ( (entryChild=psListGetNext(iter)) != NULL) {
+        printMetadataItem(entryChild, spaces);
+    }
+
+    psFree(iter);
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    psS32 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 printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key pType: %d  ", metadataItem->pType);
+    printf("Key mdType: %d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->data.V && metadataItem->type==PS_META_LIST) {
+        printMetadataList(metadataItem->data.V, "    ");
+    }
+}
+
+
+psS32 main(psS32 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;
+    psU32 failedLines1 = 0;
+    metadata1 = psMetadataParseConfig(metadata1, &failedLines1, "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;
+    psS32 failedLines2 = 0;
+    metadata2 = psMetadataParseConfig(metadata2, &failedLines2, "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();
+    psS32 failedLines3 = 0;
+    metadata3 = psMetadataParseConfig(metadata3, &failedLines3, "test.config", true);
+    printf("Failed lines: %d Expected: 6 ", 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, &failedLines1, 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, &failedLines1, "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);
+    if(psMemCheckLeaks(0, NULL, stdout,false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leak detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/astronomy/tst_psMetadata_01.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_01.c	(revision 3057)
@@ -0,0 +1,268 @@
+/** @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 - Read named hdr w/ invalid extnum
+*     Test K - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.17 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 02:50:15 $
+*
+*  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 printMetadata(psMetadata *metadata);
+static void printMetadataList(psList *metadataItemList, char* spaces);
+static void printMetadataTable(psHash *mdTable);
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list, " ");
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+static void printMetadataList(psList *metadataItemList, char* spaces)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListIterator* iter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD);
+
+    while ( (entryChild=psListGetNext(iter)) != NULL) {
+        printMetadataItem(entryChild, spaces);
+    }
+
+    psFree(iter);
+
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    psS32 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 printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key pType: %d  ", metadataItem->pType);
+    printf("Key mdType: %d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->data.V && metadataItem->type==PS_META_LIST) {
+        printMetadataList(metadataItem->data.V, "    ");
+    }
+}
+
+
+psS32 main(psS32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataReadHeader did not return null invalid extname give.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use bad extName", true);
+
+
+    // Test J - Read named hdr w/ invalid extnum
+    printNegativeTestHeader(stdout, "psMetadata", "Test J - Read named hdr w/ invalid extnum",
+                            "If extName specified, extNum should be -1.", 0);
+    metadata1 = psMetadataReadHeader(NULL, NULL, 0, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataReadHeader did not return null w/ valid extname, invalid extnum");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test J - Read named hdr w/ invalid extnum", true);
+
+
+    // Test K - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test K - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    if(psMemCheckLeaks(0, NULL, stdout,false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test K - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psMetadata_02.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_02.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_02.c	(revision 3057)
@@ -0,0 +1,151 @@
+/** @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.9 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_F32, PS_META_PRIMITIVE, "I am a single precision floating point", 222.222);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double precision floating point", 333.333);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_PTR, 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_TYPE_PTR, PS_META_STR, "I am a string", "HELLO WORLD");
+    if (badItem != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"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_TYPE_PTR, PS_META_NTYPE, "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);
+    if(psMemCheckLeaks(0, NULL, stdout,false) ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/astronomy/tst_psMetadata_03.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_03.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_03.c	(revision 3057)
@@ -0,0 +1,248 @@
+/** @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 - Attempt to add item to an invalid metadata structure
+*     Test H - Attempt to add item to an invalid metadata structure
+*     Test I - Attempt to add item with a null name
+*     Test J - Attempt to add item to an invalid metadata structure
+*     Test K - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.11 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    errItem = psMetadataItemAlloc("errItem", PS_TYPE_S32, PS_META_PRIMITIVE, "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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by name.");
+        return 10;
+    }
+    if(!psMetadataAdd(metadata,PS_LIST_HEAD,"myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am S32 integer",77)) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by name.");
+        return 11;
+    }
+    if (!psMetadataRemove(metadata, 0, "myItem1")) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return true when removing by name.");
+        return 12;
+    }
+    if (!psMetadataRemove(metadata, 0, "myItem2")) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by index.");
+        return 14;
+    }
+    if ( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am S32 integer",88) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by index.");
+        return 15;
+    }
+    if( ! psMetadataRemove(metadata, 0, NULL) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return true when removing by index.");
+        return 16;
+    }
+    if ( ! psMetadataRemove(metadata, 0, NULL ) ) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 G - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test G - 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 21;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return false w/ invalid metadata struct w/o hash table.");
+        return 31;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test G - Attempt to add item to invalid metadata w/o hash table", 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 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o link list.");
+        return 22;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return false w/ invalid metadata struct w/o link list.");
+        return 32;
+    }
+    errMetadata->list = mdList;
+    printFooter(stdout,"psMetadata","Test H - Attempt to add item to invalid metadata w/o link list", true);
+
+    // Test I - Attempt to add item with a null name
+    printNegativeTestHeader(stdout,"psMetadata","Test I - 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false with item with null name.");
+        return 23;
+    }
+    errItem->name = errName;
+    printFooter(stdout,"psMetadata","Test I - Attempt to add item with null name", 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 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_TYPE_S32, PS_META_PRIMITIVE, "Integer",22) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 24;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test J - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test K - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test K - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(errItem);
+    psFree(errMetadata);
+    if( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test K - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psMetadata_04.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_04.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_04.c	(revision 3057)
@@ -0,0 +1,298 @@
+
+/** @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 - Lookup metadata item and return psS32 value
+*     Test H - Lookup metadata item and return psF64 value
+*     Test I - Lookup metadata item and return psVector pointer
+*     Test J - Attempt to use null metadata
+*     Test K - Attempt to get non-existant metadata item
+*     Test L - Attempt to look up with an invalid metadata object
+*     Test M - Attempt get item  with an invalid metadata object
+*     Test N - Attempt get value of non-existant metadata item
+*     Test O - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.11 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2005-01-13 21:19: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)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psBool status = 0;
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = 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");
+    psVector *vec = psVectorAlloc(5, PS_TYPE_S32);
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_TYPE_PTR, PS_META_VEC, "I am a vector", vec);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printMetadataItem(item5);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item5, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item6, 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 - Lookup metadata item and return psS32 value
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value");
+    psS32 valueS32 = 0;
+    valueS32 = psMetadataLookupS32(metadata, "myItem2", &status);
+    if(valueS32 != 55) {
+        printf("ERROR: Bad value, %d, Expected 55\n", valueS32);
+        return 15;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 15;
+    }
+    printFooter(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value", true);
+
+    // Test H - Lookup metadata item and return psF64 value
+    printPositiveTestHeader(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value");
+    psF64 valueF64 = 0.0;
+    valueF64 = psMetadataLookupF64(metadata, "myItem5", &status);
+    if(fabs(valueF64-3.14) > FLT_EPSILON) {
+        printf("ERROR: Bad value, %g, Expected 3.14\n", valueF64);
+        return 16;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 16;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value", true);
+
+    // Test I - Lookup metadata item and return psVector pointer
+    printPositiveTestHeader(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer");
+    psVector *valueVec = NULL;
+    valueVec = psMetadataLookupPtr(metadata, "myItem6", &status);
+    if(valueVec != vec) {
+        printf("ERROR: Bad vector pointer\n");
+        return 17;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 17;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer", true);
+
+
+    // Test J - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test J - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    item = psMetadataGet(NULL, 0);
+    if ( item != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with null metadata structure");
+        return 18;
+    }
+    printFooter(stdout, "psMetadata", "Test J - Attempt to use null metadata", true);
+
+
+    // Test K - Attempt to get non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test K - Attempt to get non-existant metadata item",
+                            "Couldn't find metadata item with given index. Index: 22", 0);
+    if ( psMetadataGet(metadata, 22) != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with non-existant metadata item");
+        return 19;
+    }
+    printFooter(stdout, "psMetadata", "Test K - Attempt to get non-existant metadata item", true);
+
+    // Test L - Attempt to look up with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test L - 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(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
+        return 20;
+    }
+    metadata->table = tmpTable;
+    printFooter(stdout, "psMetadata","Test L - Attempt to lookup an invalid metadata object.",true);
+
+    // Test M - Attempt get item with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test M - Attempt 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(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
+        return 21;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata","Test M - Attempt to get item with  invalid metadata object",true);
+
+    // Test N - Attempt get psS32 value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test N - Attempt get psS32 value of non-existant metadata item");
+    valueS32 = psMetadataLookupS32(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 22;
+    }
+    printFooter(stdout, "psMetadata","Test N - Attempt get psS32 value of non-existant metadata item",true);
+
+    // Test O - Attempt get psF64 value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test O - Attempt get psF64 value of non-existant metadata item");
+    valueF64 = psMetadataLookupF64(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 23;
+    }
+    printFooter(stdout, "psMetadata","Test O - Attempt get psF64 value of non-existant metadata item",true);
+
+    // Test P - Attempt get psVector value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test P - Attempt get psVector value of non-existant metadata item");
+    valueVec = psMetadataLookupPtr(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 24;
+    }
+    printFooter(stdout, "psMetadata","Test P - Attempt get psVector value of non-existant metadata item",true);
+
+    // Test Q - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test Q - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(item6);
+    if ( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"memory leaks detected.");
+        return 23;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 24;
+    }
+    printFooter(stdout, "psMetadata", "Test Q - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psMetadata_05.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_05.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_05.c	(revision 3057)
@@ -0,0 +1,327 @@
+
+
+/** @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.16 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2005-01-13 23:34:56 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = NULL;
+    psMetadataItem *item7 = NULL;
+    //    psMetadataItem *item8 = NULL;
+    psMetadata *metadata = NULL;
+    FILE *fd = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_F32, PS_META_PRIMITIVE, "I am a float", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_TYPE_F64, PS_META_PRIMITIVE,"I am a double", 6.28);
+    item7 = psMetadataItemAlloc("myItem7", PS_TYPE_PTR, PS_META_STR, "I am a string", "GNIRTS");
+    //    item8 = psMetadataItemAlloc("myItem8", PS_TYPE_PTR, 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");
+        if (!psMetadataSetIterator(metadata, 2)) {
+            psError(PS_ERR_UNKNOWN,true,"Failed to set iterator");
+            return 100;
+        }
+        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(PS_ERR_UNKNOWN, true,"psMetadataGetPrevious did not return an item from metadata.");
+            return 45;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if ( psMetadataGetPrevious(metadata,NULL,1) != NULL) {
+            psError(PS_ERR_UNKNOWN, true,"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");
+    }
+
+    if (psMetadataItemPrint(fd, "S32 = %ld\n", item2) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 10;
+    }
+
+    if (psMetadataItemPrint(fd, "BOL = %ld\n", item3) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 11;
+    }
+
+    if (psMetadataItemPrint(fd, "F32 = %g\n", item5) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 12;
+    }
+
+    if (psMetadataItemPrint(fd, "F64 = %g\n", item6) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 13;
+    }
+
+    if (psMetadataItemPrint(fd, "STR = %s\n", item7) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 14;
+    }
+    //    psLogMsg(__func__,PS_LOG_INFO,"Attempt to print item of invalid type, should generate error message");
+    //    if (psMetadataItemPrint(fd, "UNK = \n", item8) == true) {
+    //        printf("ERROR: Return type should be false\n");
+    //        fclose(fd);
+    //        return 15;
+    //    }
+    fclose(fd);
+
+    fd = fopen("./tst_psMetadata05_OUT", "r");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for reading\n");
+    }
+
+    char line[256];
+    char truth1[] = "S32 = 55";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth1, 8)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth1);
+    }
+
+    char truth2[] = "BOL = 0";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth2, 7)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth2);
+    }
+
+    char truth3[] = "F32 = 3.14";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth3, 10)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth3);
+    }
+
+    char truth4[] = "F64 = 6.28";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth4, 10)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth4);
+    }
+
+    char truth5[] = "STR = GNIRTS";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth5, 12)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth5);
+    }
+
+    fclose(fd);
+    printFooter(stdout, "psMetadata", "Test F - Write metadata item to file", true);
+    /*
+        // 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);
+        if( psMetadataSetIterator(NULL, 0)) {
+            psError(PS_ERR_UNKNOWN,true,"Set iterator did not detect invalid parameter.");
+            return 101;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if( psMetadataSetIterator(metadata,0)) {
+            psError(PS_ERR_UNKNOWN,true,"Set iterator did not detect null list.");
+            return 102;
+        }
+        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(PS_ERR_UNKNOWN, true,"psMetadataGetNext did not return null for null metadata.");
+            return 40;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if ( psMetadataGetNext(metadata, "myItem2", 0) != NULL ) {
+            psError(PS_ERR_UNKNOWN, true,"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, false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 50;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/astronomy/tst_psMetadata_06.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_06.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_06.c	(revision 3057)
@@ -0,0 +1,147 @@
+
+/** @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.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item1b = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
+    item1c = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 222);
+    item2a = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 333);
+    item2b = psMetadataItemAlloc("myItem2", PS_TYPE_PTR, PS_META_LIST, "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(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node top.");
+        return 20;
+    }
+    if (!psMetadataAddItem(metadata, item1b, PS_LIST_HEAD)) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node to existing leaf node.");
+        return 23;
+    }
+    if (!psMetadataAddItem(metadata, item2b, PS_LIST_HEAD)) {
+        psError(PS_ERR_UNKNOWN, true,"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, false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/astronomy/tst_psMetadata_07.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psMetadata_07.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psMetadata_07.c	(revision 3057)
@@ -0,0 +1,46 @@
+/** @file  tst_psMetadata_07.c
+*
+*  @brief Test driver for psMetadataIO functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read an XML config file
+*     Test B - Free data
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:38:41 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+#include "pslib.h"
+#include "psTest.h"
+
+
+int main(int argc, char* argv[])
+{
+    // Test A - Read an XML config file
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read an XML config file");
+    int res = 0;
+    psU32 nFail = 0;
+    psMetadata *md = NULL;
+    md = psMetadataParseConfigXml(md, &nFail, "../../config/psTime.xml", true);
+    if (nFail != 0) {
+        printf("psMetadataParseConfigXml returned error %d\n", res);
+    }
+    psFree(md);
+    printFooter(stdout, "psMetadata", "Test A - Read an XML config file", true);
+
+
+    // Test B - Free data
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Free data");
+    psMemCheckLeaks(0, NULL, stdout, false);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test B - Free data", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psTime_01.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psTime_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psTime_01.c	(revision 3057)
@@ -0,0 +1,229 @@
+/** @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 data
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.17 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-10 02:50:15 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+psS32 main(psS32 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 = %lld Microseconds = %u\n",
+           (long long int)testTime->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeD->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeE->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeF->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeH->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeJ->sec,
+           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 = %lld Microseconds = %lld\n",
+           (long long int)timevalTime.tv_sec,
+           (long long int)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 = %lld Microseconds = %u\n",
+           (long long int)timeL->sec,
+           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 = %lld Microseconds = %u\n",
+           (long long int)timeN->sec,
+           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 data
+    printPositiveTestHeader(stdout, "psMetadata", "Test P - Free data");
+    psFree(testTime);
+    psLibFinalize();
+    if( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test P - Free data", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psTime_02.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psTime_02.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psTime_02.c	(revision 3057)
@@ -0,0 +1,56 @@
+/** @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
+ *     C) Free data
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.8 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 20:52:45 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+psS32 main(psS32 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 data
+    printPositiveTestHeader(stdout, "psTime", "Test C - Free data");
+    if ( psMemCheckLeaks(0, NULL, stdout,false) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psTime", "Test C - Free data", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psTime_03.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psTime_03.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psTime_03.c	(revision 3057)
@@ -0,0 +1,216 @@
+
+/** @file  tst_psTime_03.c
+ *
+ *  @brief Test driver for psTime functions
+ *
+ *  This test driver contains the following tests for psTime:
+ *
+ *   Test A - Add two times
+ *   Test B - Add two times with overflow in microseconds
+ *   Test C - Subtact two times
+ *   Test D - Subtact two times with underflow in microseconds
+ *   Test E - Delta two times
+ *   Test F - Delta two times with underflow in microseconds
+ *   Test G - Add two times across leapsecond boundary
+ *   Test H - Find number of leapseconds added between two times
+ *   Test H1 - Verify error message to invalid time type in psTimeAlloc
+ *   Test G - Free data
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2005-01-13 01:58:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_TIME(TEXT,TIME) \
+printf("%s Seconds = %lld Microseconds = %u\n", TEXT, (long long int)TIME->sec, TIME->usec);
+
+psS32 main(psS32 argc, char* argv[])
+{
+
+    // Test A - Add two times
+    printPositiveTestHeader(stdout, "psTime", "Test A - Add two times");
+    psTime *time1a = NULL;
+    psF64 time1b = 1.111111;
+    psTime *timeOut1 = NULL;
+    time1a = psTimeAlloc(PS_TIME_TAI);
+    time1a->sec  = 1;
+    time1a->usec = 111111;
+    timeOut1 = psTimeMath(time1a, time1b);
+    if(timeOut1->sec!=2 && timeOut1->usec!=222222) {
+        printf("ERROR: Incorrect time, %lld:%u. Expected 2:222222\n",(long long int)timeOut1->sec, timeOut1->usec);
+    }
+    printFooter(stdout, "psTime", "Test A - Add two times", true);
+
+
+    // Test B - Add two times with overflow in microseconds
+    printPositiveTestHeader(stdout, "psTime", "Test B - Add two times with overflow in microseconds");
+    psTime *time2a = NULL;
+    psF64 time2b = 5.500001;
+    psTime *timeOut2 = NULL;
+    time2a = psTimeAlloc(PS_TIME_TAI);
+    time2a->sec  = 6;
+    time2a->usec = 600001;
+    timeOut2 = psTimeMath(time2a, time2b);
+    if(timeOut2->sec!=12 && timeOut2->usec!=100002) {
+        printf("ERROR: Incorrect time, %lld:%u. Expected 12:100002\n",(long long int)timeOut2->sec, timeOut2->usec);
+    }
+    printFooter(stdout, "psTime", "Test B - Add two times with overflow in microseconds", true);
+
+
+    // Test C - Subtact two times
+    printPositiveTestHeader(stdout, "psTime", "Test C - Subtract two times");
+    psTime *time3a = NULL;
+    psF64 time3b = -1.111111;
+    psTime *timeOut3 = NULL;
+    time3a = psTimeAlloc(PS_TIME_TAI);
+    time3a->sec  = 3;
+    time3a->usec = 333333;
+    timeOut3 = psTimeMath(time3a, time3b);
+    if(timeOut3->sec!=2 && timeOut3->usec!=222222) {
+        printf("ERROR: Incorrect time, %lld:%u. Expected 2:222222\n",(long long int)timeOut3->sec, timeOut3->usec);
+    }
+    printFooter(stdout, "psTime", "Test C - Subtract two times", true);
+
+
+    // Test D - Subtact two times with underflow in microseconds
+    printPositiveTestHeader(stdout, "psTime", "Test D - Subtact two times with underflow in microseconds");
+    psTime *time4a = NULL;
+    psF64 time4b = -2.000003;
+    psTime *timeOut4 = NULL;
+    time4a = psTimeAlloc(PS_TIME_TAI);
+    time4a->sec  = 5;
+    time4a->usec = 1;
+    timeOut4 = psTimeMath(time4a, time4b);
+    if(timeOut4->sec!=2 && timeOut4->usec!=999997) {
+        printf("ERROR: Incorrect time, %lld:%u. Expected 2:999997\n",(long long int)timeOut4->sec, timeOut4->usec);
+    }
+    printFooter(stdout, "psTime", "Test D - Subtact two times with underflow in microseconds", true);
+
+
+    // Test E - Delta two times
+    printPositiveTestHeader(stdout, "psTime", "Test E - Delta two times");
+    psTime *time5a = NULL;
+    psTime *time5b = NULL;
+    psF64 timeOut5 = 0.0;
+    time5a = psTimeAlloc(PS_TIME_TAI);
+    time5b = psTimeAlloc(PS_TIME_TAI);
+    time5a->sec  = 8;
+    time5a->usec = 8;
+    time5b->sec  = 7;
+    time5b->usec = 7;
+    timeOut5 = psTimeDelta(time5a, time5b);
+    if(fabs(timeOut5-1.000001) > FLT_EPSILON) {
+        printf("ERROR: Incorrect delta, %lf. Expected -1.000001\n", timeOut5);
+    }
+    printFooter(stdout, "psTime", "Test E - Delta two times", true);
+
+
+    // Test F - Delta two times with underflow in microseconds
+    printPositiveTestHeader(stdout, "psTime", "Test F - Delta two times with underflow in microseconds");
+    psTime *time6a = NULL;
+    psTime *time6b = NULL;
+    psF64 timeOut6 = 0.0;
+    time6a = psTimeAlloc(PS_TIME_TAI);
+    time6b = psTimeAlloc(PS_TIME_TAI);
+    time6a->sec  = 8;
+    time6a->usec = 1;
+    time6b->sec  = 7;
+    time6b->usec = 7;
+    timeOut6 = psTimeDelta(time6a, time6b);
+    if(fabs(timeOut6-0.999994) > FLT_EPSILON) {
+        printf("ERROR: Incorrect delta, %lf. Expected 0.999994\n", timeOut6);
+    }
+    printFooter(stdout, "psTime", "Test F - Delta two times with underflow in microseconds", true);
+
+    // Test F1 - Delta two times in UTC type
+    printPositiveTestHeader(stdout,"psTime","Test F1 - Delta two UTC times");
+    psTime *time20a = NULL;
+    psTime *time20b = NULL;
+    psF64 timeOut20 = 0.0;
+    time20a = psTimeAlloc(PS_TIME_UTC);
+    time20b = psTimeAlloc(PS_TIME_UTC);
+    time20a->sec = 1090434113;
+    time20a->usec = 272044;
+    time20b->sec = 1090434112;
+    time20b->usec = 272044;
+    timeOut20 = psTimeDelta(time20a, time20b);
+    if(fabs(timeOut20-1.000000000) > FLT_EPSILON) {
+        printf("ERROR: Incorrect delta, %lf. Expected -1.00000\n",timeOut20);
+    }
+    printFooter(stdout,"psTime","Test F1 - Delta two UTC times",true);
+
+    // Test G - Add two times across leapsecond boundary
+    printPositiveTestHeader(stdout, "psTime", "Test G - Add two times across leapsecond boundary");
+    psF64 time7b = 30.0;
+    char *out7 = NULL;
+    psTime *time7a = NULL;
+    psTime *timeOut7 = NULL;
+    time7a = psTimeFromISOTime("1998-12-31T23:59:45.00");
+    time7a->type = PS_TIME_UTC;
+    timeOut7 = psTimeMath(time7a, time7b);
+    out7 = psTimeToISOTime(timeOut7);
+    printf("%s\n", out7);
+    printFooter(stdout, "psTime", "Test G - Add two times across leapsecond boundary", true);
+
+
+    // Test H - Find number of leapseconds added between two times
+    printPositiveTestHeader(stdout, "psTime", "Test H - Find number of leapseconds added between two times");
+    psS64 out = 0.0;
+    psTime *time8a = NULL;
+    psTime *time8b = NULL;
+    time8a = psTimeFromISOTime("2004-12-18T1:00:00.00");
+    time8b = psTimeFromISOTime("1972-1-1T1:00:00.00");
+    out = psTimeLeapseconds(time8a, time8b);
+    printf("%lld\n", (long long int)out);
+    printFooter(stdout, "psTime", "Test H - Find number of leapseconds added between two times", true);
+
+    // Test H1 - Error in allocating time not UTC or TAI
+    printPositiveTestHeader(stdout,"psTime","Test H1 - Verify error message in allocating invalid time type");
+    psLogMsg(__func__,PS_LOG_INFO,"Invalid time type during allocation should generate error message");
+    psTime *time10 = psTimeAlloc(10);
+    if(time10 != NULL) {
+        printf("ERROR: returned time should be NULL\n");
+    }
+    printFooter(stdout,"psTime","Test H1 - Verify error message in allocating invalid time type",true);
+
+    // Test G - Free data
+    printPositiveTestHeader(stdout, "psTime", "Test I - Free data");
+    psLibFinalize();
+    psFree(time1a);
+    psFree(timeOut1);
+    psFree(time2a);
+    psFree(timeOut2);
+    psFree(time3a);
+    psFree(timeOut3);
+    psFree(time4a);
+    psFree(timeOut4);
+    psFree(time5a);
+    psFree(time5b);
+    psFree(time6a);
+    psFree(time6b);
+    psFree(out7);
+    psFree(time7a);
+    psFree(timeOut7);
+    psFree(time8a);
+    psFree(time8b);
+    psFree(time20a);
+    psFree(time20b);
+    if (psMemCheckLeaks(0, NULL, stdout,false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psTime", "Test I - Free data", true);
+    return 0;
+}
Index: /branches/rel4/psLib/test/astronomy/tst_psTime_04.c
===================================================================
--- /branches/rel4/psLib/test/astronomy/tst_psTime_04.c	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/tst_psTime_04.c	(revision 3057)
@@ -0,0 +1,91 @@
+/** @file  tst_psTime_04.c
+ *
+ *  @brief Test driver for psTime functions
+ *
+ *  This test driver contains the following tests for psTime:
+ *      Test A - Initialize time
+ *      Test B - Attempt to open non-existant time config file
+ *      Test C - Attempt to open non-existant time data files
+ *      Test D - Attempt to read incorrect number of files
+ *      Test E - Attempt to read incorrect number of from values
+ *      Test F - Attempt to read data file with typo in number
+ *      Test G - Free data
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-16 18:53:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+
+int main(int argc, char* argv[])
+{
+    // Test A - Initialize time
+    printPositiveTestHeader(stdout, "psTime", "Test A - Initialize time");
+    psLibInit(true, "../../config/psTime.config");
+    psLibFinalize();
+    printFooter(stdout, "psTime", "Test A - Initialize time", true);
+
+
+    // Test B - Attempt to open non-existant time config file
+    printNegativeTestHeader(stdout,"psTime", "Test B - Attempt to open non-existant time config file",
+                            "Failed to open file 'zzz'.  Check if it exists and it has the proper permissions.", 0);
+    psLibInit(true, "zzz");
+    printFooter(stdout, "psTime", "Test B - Attempt to open non-existant time config file", true);
+
+
+    // Test C - Attempt to open non-existant time data files
+    printNegativeTestHeader(stdout,"psTime", "Test C - Attempt to open non-existant time data files",
+                            "Failed to open file 'zzz'.  Check if it exists and it has the proper permissions.", 0);
+    psLibInit(true, "./test.psTime.config1");
+    psLibFinalize();
+    printFooter(stdout, "psTime", "Test C - Attempt to open non-existant time data files", true);
+
+
+    // Test D - Attempt to read incorrect number of files
+    printNegativeTestHeader(stdout,"psTime", "Test D - Attempt to read incorrect number of files",
+                            "Incorrect number of table files entered. Found: 3. Expected: 4.", 0);
+    psLibInit(true, "./test.psTime.config2");
+    psLibFinalize();
+    printFooter(stdout, "psTime", "Test D - Attempt to read incorrect number of files", true);
+
+
+    // Test E - Attempt to read incorrect number of from values
+    printNegativeTestHeader(stdout,"psTime", "Test E - Attempt to read incorrect number of from values",
+                            "Incorrect vector size. Size: 3, Expected 4.", 0);
+    psLibInit(true, "./test.psTime.config3");
+    psLibFinalize();
+    printFooter(stdout, "psTime", "Test E - Attempt to read incorrect number of from values", true);
+
+
+    // Test F - Attempt to read data file with typo in number
+    printNegativeTestHeader(stdout,"psTime", "Test F - Attempt to read data file with typo in number",
+                            "Unable to parse string, number on line 16.", 0);
+    psLibInit(true, "./test.psTime.config4");
+    psLibFinalize();
+    printFooter(stdout, "psTime", "Test F - Attempt to read data file with typo in number", true);
+
+
+    // Test G - Free data
+    printPositiveTestHeader(stdout, "psTime", "Test G - Free data");
+    psLibFinalize();
+    if( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leak detected.");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psTime", "Test G - Free data", true);
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psAstrometry.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psAstrometry.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psAstrometry.stderr	(revision 3057)
@@ -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/rel4/psLib/test/astronomy/verified/tst_psCoord.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psCoord.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psCoord.stderr	(revision 3057)
@@ -0,0 +1,169 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereTransformAlloc()}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psCoord{psSphereTransformAlloc()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPlaneTransformAlloc()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psPlaneTransformAlloc (psCoord.c:<LINENO>)
+    Error: n1 is less than 0.
+<DATE><TIME>|<HOST>|E|psPlaneTransformAlloc (psCoord.c:<LINENO>)
+    Error: n2 is less than 0.
+
+---> TESTPOINT PASSED (psCoord{psPlaneTransformAlloc()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPlaneDistortAlloc()}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psPlaneDistortAlloc (psCoord.c:<LINENO>)
+    Error: n1 is less than 0.
+<DATE><TIME>|<HOST>|E|psPlaneDistortAlloc (psCoord.c:<LINENO>)
+    Error: n2 is less than 0.
+<DATE><TIME>|<HOST>|E|psPlaneDistortAlloc (psCoord.c:<LINENO>)
+    Error: n3 is less than 0.
+<DATE><TIME>|<HOST>|E|psPlaneDistortAlloc (psCoord.c:<LINENO>)
+    Error: n4 is less than 0.
+
+---> TESTPOINT PASSED (psCoord{psPlaneDistortAlloc()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPlaneTransformApply()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psPlaneTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform->x is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform->y is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: coords is NULL.
+
+---> TESTPOINT PASSED (psCoord{psPlaneTransformApply()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPlaneDistortApply()}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psPlaneDistortApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneDistortApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform->x is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneDistortApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform->y is NULL.
+<DATE><TIME>|<HOST>|E|psPlaneDistortApply (psCoord.c:<LINENO>)
+    Unallowable operation: coords is NULL.
+
+---> TESTPOINT PASSED (psCoord{psPlaneDistortApply()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPSphereTransformApply()}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psSphereTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: transform is NULL.
+<DATE><TIME>|<HOST>|E|psSphereTransformApply (psCoord.c:<LINENO>)
+    Unallowable operation: coord is NULL.
+
+---> TESTPOINT PASSED (psCoord{psPSphereTransformApply()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psPSphereTransformApply()}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psCoord{psPSphereTransformApply()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereTransformICRSToEcliptic()}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psSphereTransformICRSToEcliptic (psCoord.c:<LINENO>)
+    Unallowable operation: time is NULL.
+
+---> TESTPOINT PASSED (psCoord{psSphereTransformICRSToEcliptic()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereTransformEclipticToICRS()}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psSphereTransformEclipticToICRS (psCoord.c:<LINENO>)
+    Unallowable operation: time is NULL.
+
+---> TESTPOINT PASSED (psCoord{psSphereTransformEclipticToICRS()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereTransformICRSToGalatic()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psCoord{psSphereTransformICRSToGalatic()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereTransformGalaticToICRS()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psCoord{psSphereTransformGalaticToICRS()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereGetOffset()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psSphereGetOffset (psCoord.c:<LINENO>)
+    Unallowable operation: position1 is NULL.
+<DATE><TIME>|<HOST>|E|psSphereGetOffset (psCoord.c:<LINENO>)
+    Unallowable operation: position2 is NULL.
+<DATE><TIME>|<HOST>|E|psSphereGetOffset (psCoord.c:<LINENO>)
+    Specified offset mode, 0x54321, is not supported.
+<DATE><TIME>|<HOST>|E|psSphereGetOffset (psCoord.c:<LINENO>)
+    Specified units, 0x54321, is not supported.
+
+---> TESTPOINT PASSED (psCoord{psSphereGetOffset()} | tst_psCoord.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psCoord.c                                              *
+*            TestPoint: psCoord{psSphereSetOffset()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psSphereSetOffset (psCoord.c:<LINENO>)
+    Unallowable operation: position is NULL.
+<DATE><TIME>|<HOST>|E|psSphereSetOffset (psCoord.c:<LINENO>)
+    Unallowable operation: offset is NULL.
+<DATE><TIME>|<HOST>|E|psSphereSetOffset (psCoord.c:<LINENO>)
+    Specified offset mode, 0x54321, is not supported.
+<DATE><TIME>|<HOST>|E|psSphereSetOffset (psCoord.c:<LINENO>)
+    Specified units, 0x54321, is not supported.
+
+---> TESTPOINT PASSED (psCoord{psSphereSetOffset()} | tst_psCoord.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psCoord.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psCoord.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psCoord.stdout	(revision 3057)
@@ -0,0 +1,59 @@
+-------------------------------------------------------------------
+Calling psPlaneTransformAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneTransformAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortAlloc() with negative-order polynomial request.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psPlaneTransformApply() with NULL psPlaneTransform.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneTransformApply() with NULL psPlaneTransform->x.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneTransformApply() with NULL psPlaneTransform->y.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneTransformApply() with NULL input coords.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psPlaneDistortApply() with NULL psPlaneDistort.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortApply() with NULL psPlaneDistort->x.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortApply() with NULL psPlaneDistort->y.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psPlaneDistortApply() with NULL input coords.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psSphereTransformApply() with NULL psSphereTransform.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereTransformApply() with NULL input coords.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psSphereTransformICRSToEcliptic() with NULL input.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereTransformEclipticToICRS() with NULL input.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereGetOffset() with NULL position1.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereGetOffset() with NULL position2.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereGetOffset() with bogus offset mode.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereGetOffset() with bogus offset units.  Should generate error, return NULL.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Calling psSphereSetOffset() with NULL position1.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereSetOffset() with NULL offset.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereSetOffset() with bogus offset mode.  Should generate error, return NULL.
+-------------------------------------------------------------------
+Calling psSphereSetOffset() with bogus offset unit.  Should generate error, return NULL.
+-------------------------------------------------------------------
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stderr	(revision 3057)
@@ -0,0 +1,42 @@
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 90 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to read a metadata value on line 96 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Metadata type '99.999', found on line 102 of test.config, is not invalid.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '*' character not allowed.  Found on line 108 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '@' character not allowed.  Found on line 114 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '~' character not allowed.  Found on line 120 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 90 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to read a metadata value on line 96 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Metadata type '99.999', found on line 102 of test.config, is not invalid.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '*' character not allowed.  Found on line 108 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '@' character not allowed.  Found on line 114 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '~' character not allowed.  Found on line 120 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Duplicate Metadata item, speed, found on line 128 of test.config.  Overwrite not allowed.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 90 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to read a metadata value on line 96 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Metadata type '99.999', found on line 102 of test.config, is not invalid.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '*' character not allowed.  Found on line 108 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '@' character not allowed.  Found on line 114 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    More than one '~' character not allowed.  Found on line 120 of test.config.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Unallowable operation: fileName is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to open file 'abcedfg'. Check if it exists and it has the proper permissions.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadataIO.stdout	(revision 3057)
@@ -0,0 +1,173 @@
+/***************************** 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 pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key pType: 0  Key mdType: 2  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          66.660  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:       pi  Key pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          66.660  Key Comment: 
+ Key Name:   title1  Key pType: 0  Key mdType: 2  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 pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key pType: 0  Key mdType: 2  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          55.550  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:       pi  Key pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          55.550  Key Comment: 
+ Key Name:   title1  Key pType: 0  Key mdType: 2  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: 6 Expected: 6 Contents of metadata list:
+ Key Name:       pi  Key pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key pType: 0  Key mdType: 2  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          66.660  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key pType: 0  Key mdType: 2  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key pType: 0  Key mdType: 2  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key pType: 1028  Key mdType: 0  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: 
+ Key Name:       pi  Key pType: 1032  Key mdType: 0  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key pType: 4865  Key mdType: 0  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key pType: 260  Key mdType: 3  Bad type: 3 Key Comment: These are prime numbers
+ Key Name: altitude  Key pType: 260  Key mdType: 0  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key pType: 1028  Key mdType: 0  Key Value:          66.660  Key Comment: 
+ Key Name:   title1  Key pType: 0  Key mdType: 2  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/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stderr	(revision 3057)
@@ -0,0 +1,18 @@
+<DATE><TIME>|<HOST>|E|psListRemoveData (psList.c:<LINENO>)
+    Specified data item is not found in the psList.
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Failed to remove metadata item, HISTORY, from metadata list.
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    Unallowable operation: fileName is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    FITS error while opening file: missing.dat could not open the named file
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    Couldn't close FITS file. FITS error: NULL input pointer
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    Specified extension number, 0, is invalid.  Value must be positive if no extension name is given.
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    FITS error while locating header 22: tried to move past end of file
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    FITS error while locating header AARGH: illegal HDU number
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader (psMetadataIO.c:<LINENO>)
+    Specified extension number, 0, is invalid.  Value must be positive if no extension name is given.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_01.stdout	(revision 3057)
@@ -0,0 +1,197 @@
+/***************************** 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 pType: 4865  Key mdType: 0  Key Value:               1  Key Comment: file does conform to FITS standard
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:               8  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: number of data axes
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: number of data axes
+ Key Name:   SIMPLE  Key pType: 4865  Key mdType: 0  Key Value:               1  Key Comment: file does conform to FITS standard
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:               8  Key Comment: number of bits per data pixel
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  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 pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  Key Value:     'MY_DATA_1'  Key Comment: 
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+    Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  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 pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  Key Value:     'MY_DATA_2'  Key Comment: 
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  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 pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  Key Value:     'MY_DATA_2'  Key Comment: 
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key pType: 260  Key mdType: 0  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key pType: 260  Key mdType: 0  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key pType: 0  Key mdType: 2  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   GCOUNT  Key pType: 260  Key mdType: 0  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key pType: 260  Key mdType: 0  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  HISTORY  Key pType: 0  Key mdType: 1  Key Value:                  Key Comment: 
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key pType: 0  Key mdType: 2  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  EXTNAME  Key pType: 0  Key mdType: 2  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 J - Read named hdr w/ invalid extnum}      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: If extName specified, extNum should be -1.                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Read named hdr w/ invalid extnum} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test K - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test K - Free psMetadata} | tst_psMetadata_01.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stderr	(revision 3057)
@@ -0,0 +1,10 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should produce error for null name.
+<DATE><TIME>|<HOST>|E|psMetadataItemAllocV (psMetadata.c:<LINENO>)
+    Unallowable operation: name is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataItemAllocV (psMetadata.c:<LINENO>)
+    Specified psMetadataType, 11, is not supported.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: md is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: metadataItem is NULL.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_02.stdout	(revision 3057)
@@ -0,0 +1,76 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key pType: 4865  Key mdType:  0  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key pType: 260  Key mdType:  0  Key Value:             111  Key Comment: I am a signed integer
+Key Name:  myItem3  Key pType: 1028  Key mdType:  0  Key Value:         222.222  Key Comment: I am a single precision floating point
+Key Name:  myItem4  Key pType: 1032  Key mdType:  0  Key Value:         333.333  Key Comment: I am a double precision floating point
+Key Name:  myItem5  Key pType:  0  Key mdType:  2  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/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stderr	(revision 3057)
@@ -0,0 +1,20 @@
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Unallowable operation: md is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Could not find metadata item, AARGH.
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Could not find metadata item at index 22.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: md->table is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Unallowable operation: md->table is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: md->list is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataRemove (psMetadata.c:<LINENO>)
+    Unallowable operation: md->list is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: metadataItem->name is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataAddItem (psMetadata.c:<LINENO>)
+    Unallowable operation: md->table is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataAdd (psMetadata.c:<LINENO>)
+    Failed to add metadata item to metadata collection list.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_03.stdout	(revision 3057)
@@ -0,0 +1,117 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key pType: 4865  Key mdType:  0  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key pType: 260  Key mdType:  0  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key pType: 4865  Key mdType:  0  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key pType: 260  Key mdType:  0  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 G - 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 G - Attempt to add item to invalid metadata w/o hash table} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test H - 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 H - Attempt to add item to invalid metadata w/o link list} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test I - Attempt to add item with null name}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't add item with null name.                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test I - Attempt to add item with null name} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test J - 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 J - Attempt to add item to invalid metadata w/o hash table} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test K - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test K - Free psMetadata} | tst_psMetadata_03.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stderr	(revision 3057)
@@ -0,0 +1,16 @@
+<DATE><TIME>|<HOST>|E|psMetadataLookup (psMetadata.c:<LINENO>)
+    Unallowable operation: md is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataLookup (psMetadata.c:<LINENO>)
+    Unallowable operation: key is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataGet (psMetadata.c:<LINENO>)
+    Unallowable operation: md is NULL.
+<DATE><TIME>|<HOST>|E|psListIteratorSet (psList.c:<LINENO>)
+    Specified location, 22, is invalid.
+<DATE><TIME>|<HOST>|E|psListGet (psList.c:<LINENO>)
+    Specified location, 22, is invalid.
+<DATE><TIME>|<HOST>|E|psMetadataGet (psMetadata.c:<LINENO>)
+    Could not find metadata item at index 22.
+<DATE><TIME>|<HOST>|E|psMetadataLookup (psMetadata.c:<LINENO>)
+    Unallowable operation: md->table is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataGet (psMetadata.c:<LINENO>)
+    Unallowable operation: md->list is NULL.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_04.stdout	(revision 3057)
@@ -0,0 +1,174 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key pType: 4865  Key mdType:  0  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key pType: 260  Key mdType:  0  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key pType: 4865  Key mdType:  0  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key pType: 260  Key mdType:  0  Key Value:              66  Key Comment: I am a integer
+Key Name:  myItem5  Key pType: 1032  Key mdType:  0  Key Value:           3.140  Key Comment: I am a double
+
+---> 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 myItem6
+
+---> TESTPOINT PASSED (psMetadata{Test F - Lookup metadata item by index} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test G - Lookup metadata item and return psS32 value} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Lookup metadata item and return psS32 value} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test H - Lookup metadata item and return psF64 value} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test H - Lookup metadata item and return psF64 value} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test I - Lookup metadata item and return psVector pointer} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test I - Lookup metadata item and return psVector pointer} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test J - Attempt to use null metadata}          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Attempt to use null metadata} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test K - 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 K - Attempt to get non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test L - Attemp to look up with an invalid metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Lookup item with invalid metadata object.                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test L - Attempt to lookup an invalid metadata object.} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test M - Attempt to get item with an invalid metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Get item with invalid metadata object.                     *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test M - Attempt to get item with  invalid metadata object} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test N - Attempt get psS32 value of non-existant metadata item} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test N - Attempt get psS32 value of non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test O - Attempt get psF64 value of non-existant metadata item} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test O - Attempt get psF64 value of non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test P - Attempt get psVector value of non-existant metadata item} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test P - Attempt get psVector value of non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test Q - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test Q - Free psMetadata} | tst_psMetadata_04.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stderr	(revision 3057)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint (psMetadataIO.c:<LINENO>)
+    Unallowable operation: fd is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint (psMetadataIO.c:<LINENO>)
+    Unallowable operation: format is NULL.
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint (psMetadataIO.c:<LINENO>)
+    Unallowable operation: metadataItem is NULL.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_05.stdout	(revision 3057)
@@ -0,0 +1,64 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key pType: 4865  Key mdType:  0  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key pType: 260  Key mdType:  0  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key pType: 4865  Key mdType:  0  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key pType: 260  Key mdType:  0  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 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 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/rel4/psLib/test/astronomy/verified/tst_psMetadata_06.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_06.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_06.stdout	(revision 3057)
@@ -0,0 +1,50 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata and items}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key pType: 4865  Key mdType:  0  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem1  Key pType: 260  Key mdType:  0  Key Value:             111  Key Comment: I am a signed integer
+Key Name:  myItem1  Key pType: 260  Key mdType:  0  Key Value:             222  Key Comment: I am a signed integer
+Key Name:  myItem2  Key pType: 260  Key mdType:  0  Key Value:             333  Key Comment: I am a signed integer
+Key Name:  myItem2  Key pType:  0  Key mdType:  1  Key Value:                  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/rel4/psLib/test/astronomy/verified/tst_psMetadata_07.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_07.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psMetadata_07.stdout	(revision 3057)
@@ -0,0 +1,18 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_07.c                                        *
+*            TestPoint: psMetadata{Test A - Read an XML config file}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test A - Read an XML config file} | tst_psMetadata_07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_07.c                                        *
+*            TestPoint: psMetadata{Test B - Free data}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Free data} | tst_psMetadata_07.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_01.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_01.stdout	(revision 3057)
@@ -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 data}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test P - Free data} | tst_psTime_01.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stderr	(revision 3057)
@@ -0,0 +1,14 @@
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: tmTime.tm_mon, 99, is out of range.  Must be between 1 and 12.
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: tmTime.tm_mday, 99, is out of range.  Must be between 1 and 31.
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: tmTime.tm_hour, 99, is out of range.  Must be between 0 and 23.
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: tmTime.tm_min, 99, is out of range.  Must be between 0 and 59.
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: tmTime.tm_sec, 99, is out of range.  Must be between 0 and 59.
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime (psTime.c:<LINENO>)
+    Error: millisecond, -999, is out of range.  Must be between 0 and 999.
+<DATE><TIME>|<HOST>|E|psTimeFromTimeval (psTime.c:<LINENO>)
+    Unallowable operation: time is NULL.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_02.stdout	(revision 3057)
@@ -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: psTime{Test C - Free data}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test C - Free data} | tst_psTime_02.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|main
+    Invalid time type during allocation should generate error message
+<DATE><TIME>|<HOST>|E|psTimeAlloc (psTime.c:<LINENO>)
+    Specified type, 10, is not supported.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_03.stdout	(revision 3057)
@@ -0,0 +1,101 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test A - Add two times}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test A - Add two times} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test B - Add two times with overflow in microseconds} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test B - Add two times with overflow in microseconds} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test C - Subtract two times}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test C - Subtract two times} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test D - Subtact two times with underflow in microseconds} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test D - Subtact two times with underflow in microseconds} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test E - Delta two times}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test E - Delta two times} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test F - Delta two times with underflow in microseconds} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test F - Delta two times with underflow in microseconds} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test F1 - Delta two UTC times}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test F1 - Delta two UTC times} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test G - Add two times across leapsecond boundary}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+1999-01-01T<DATE>.000Z
+
+---> TESTPOINT PASSED (psTime{Test G - Add two times across leapsecond boundary} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test H - Find number of leapseconds added between two times} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+22
+
+---> TESTPOINT PASSED (psTime{Test H - Find number of leapseconds added between two times} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test H1 - Verify error message in allocating invalid time type} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test H1 - Verify error message in allocating invalid time type} | tst_psTime_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_03.c                                            *
+*            TestPoint: psTime{Test I - Free data}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test I - Free data} | tst_psTime_03.c)
+
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stderr
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stderr	(revision 3057)
@@ -0,0 +1,20 @@
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig (psMetadataIO.c:<LINENO>)
+    Failed to open file 'zzz'. Check if it exists and it has the proper permissions.
+<DATE><TIME>|<HOST>|E|psLibInit (psConfigure.c:<LINENO>)
+    Failed to initialize psTime.
+<DATE><TIME>|<HOST>|E|psLookupTableRead (psLookupTable.c:<LINENO>)
+    Failed to open file ../../dataxz/ser7.dat.
+<DATE><TIME>|<HOST>|E|psLookupTableRead (psLookupTable.c:<LINENO>)
+    Failed to open file ../../dataxz/eopc01_1900_2004.dat.
+<DATE><TIME>|<HOST>|E|psLookupTableRead (psLookupTable.c:<LINENO>)
+    Failed to open file ../../dataxz/finals_all.dat.
+<DATE><TIME>|<HOST>|E|psLookupTableRead (psLookupTable.c:<LINENO>)
+    Failed to open file ../../dataxz/tai_utc.dat.
+<DATE><TIME>|<HOST>|E|p_psTimeInit (psTime.c:<LINENO>)
+    Incorrect number of table files entered. Found: 3. Expected: 4.
+<DATE><TIME>|<HOST>|E|p_psTimeInit (psTime.c:<LINENO>)
+    Incorrect vector size. Size: 3, Expected 4.
+<DATE><TIME>|<HOST>|E|psLibInit (psConfigure.c:<LINENO>)
+    Failed to initialize psTime.
+<DATE><TIME>|<HOST>|E|printError (psLookupTable.c:<LINENO>)
+    Unable to parse string, 53yyy244 on line 16.
Index: /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stdout
===================================================================
--- /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/astronomy/verified/tst_psTime_04.stdout	(revision 3057)
@@ -0,0 +1,73 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test A - Initialize time}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test A - Initialize time} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test B - Attempt to open non-existant time config file} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Failed to open file 'zzz'.  Check if it exists and it has the proper permissions. *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test B - Attempt to open non-existant time config file} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test C - Attempt to open non-existant time data files} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Failed to open file 'zzz'.  Check if it exists and it has the proper permissions. *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test C - Attempt to open non-existant time data files} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test D - Attempt to read incorrect number of files} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Incorrect number of table files entered. Found: 3. Expected: 4. *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test D - Attempt to read incorrect number of files} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test E - Attempt to read incorrect number of from values} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Incorrect vector size. Size: 3, Expected 4.                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test E - Attempt to read incorrect number of from values} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test F - Attempt to read data file with typo in number} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Unable to parse string, number on line 16.                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test F - Attempt to read data file with typo in number} | tst_psTime_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_04.c                                            *
+*            TestPoint: psTime{Test G - Free data}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Test G - Free data} | tst_psTime_04.c)
+
Index: /branches/rel4/psLib/test/collections/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/collections/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/collections/.cvsignore	(revision 3057)
@@ -0,0 +1,35 @@
+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_psArray02
+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_psHash05
+tst_psBitSet
+tst_psArray01
+tst_psScalar
Index: /branches/rel4/psLib/test/collections/Makefile
===================================================================
--- /branches/rel4/psLib/test/collections/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/collections/Makefile	(revision 3057)
@@ -0,0 +1,60 @@
+################################################################################
+##
+##  Makefile:   test/collections
+##
+##  $Revision: 1.27 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-03 20:28: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_psVector          \
+         tst_psArray           \
+         tst_psArray01         \
+         tst_psArray02         \
+         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          \
+         tst_psHash05          \
+         tst_psScalar
+
+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/rel4/psLib/test/collections/tst_psArray.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psArray.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psArray.c	(revision 3057)
@@ -0,0 +1,219 @@
+/** @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)  Reallocate with null pointer
+ *     F)  Remove item from array
+ *     G)  Remove invalid item from array
+ *     H)  Remove item from null array
+ *     I)  Remove null item from array
+ *     J)  Free void pointer array
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.9 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:07:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <math.h>
+
+#include "pslib.h"
+#include "psTest.h"
+
+typedef struct
+{
+    psS32 x;
+    float y;
+}
+testStruct;
+
+
+psS32 main(psS32 argc,
+           char* argv[])
+{
+    // Create array of pointers
+    testStruct *mySt[10];
+    psArray *psArr1 = NULL;
+
+    // Test A - Create void pointer array
+    printPositiveTestHeader(stdout,"psArray", "Create void pointer array");
+    psArray *psArr = psArrayAlloc(5);
+    if (psArr->nalloc != 5) {
+        psError(PS_ERR_UNKNOWN, true,"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(psS32 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(psS32 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(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
+            return 2;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 5) {
+        psError(PS_ERR_UNKNOWN, true,"Array Size wrong");
+        return 3;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 5) {
+        psError(PS_ERR_UNKNOWN, true,"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(psS32 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(psS32 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(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
+            return 5;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 10) {
+        psError(PS_ERR_UNKNOWN, true,"Array Size wrong");
+        return 6;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 10) {
+        psError(PS_ERR_UNKNOWN, true,"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(psS32 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(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
+            return 8;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 3) {
+        psError(PS_ERR_UNKNOWN, true,"Array Size wrong");
+        return 9;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 3) {
+        psError(PS_ERR_UNKNOWN, true,"Array Population wrong");
+        return 10;
+    }
+    printFooter(stdout, "psArray", "Reallocate integer void pointer smaller", true);
+
+    // Test E - Reallocate with a null
+    printNegativeTestHeader(stdout,"psArray","Reallocate with a null array",
+                            "Error message generator", 0 );
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    psArr1 = psArrayRealloc(NULL,5);
+    if ( psArr1 != NULL ) {
+        printf("ERROR: Return is not NULL\n");
+    }
+    printFooter(stdout,"psArray","Reallocate with a null array",true);
+
+
+    // Test F - Remove item from array
+    printPositiveTestHeader(stdout, "psArray", "Remove valid item");
+    if( !psArrayRemove(psArr,mySt[0]) ) {
+        psError(PS_ERR_UNKNOWN,true,"Unable to remove valid item");
+        return 100;
+    }
+    printf("Array size after removal = %d\n",psArr->n);
+    if ( psArr->n != 2 ) {
+        psError(PS_ERR_UNKNOWN, true, "Items in array not decremented after removal");
+        return 101;
+    }
+    for(psS32 i = 0; i < psArr->n; 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+1)) > 0.01f || fabsf(ts->y - 10.1*(i+1)) > 0.01f) {
+            psError(PS_ERR_UNKNOWN, true, "Elements not as expected after remove.");
+            return 102;
+        }
+    }
+    psFree(mySt[0]);
+    printFooter(stdout,"psArray","Remove valid item", true);
+
+    // Test G - Remove invalid item from array
+    printPositiveTestHeader(stdout, "psArray", "Remove invalid item from array");
+    if( psArrayRemove(psArr,mySt[9]) ) {
+        psError(PS_ERR_UNKNOWN,true,"Removed invalid item from array");
+        return 103;
+    }
+    printFooter(stdout,"psArray","Remove invalid item from array",true);
+
+    // Test H - Remove item from null array
+    printPositiveTestHeader(stdout, "psArray", "Remove item from null array");
+    if ( psArrayRemove(NULL,mySt[1]) ) {
+        psError(PS_ERR_UNKNOWN,true,"Removed valid item from null array");
+        return 104;
+    }
+    printFooter(stdout,"psArray","Remove item from null array",true);
+
+    // Test I - Remove null item from array
+    printPositiveTestHeader(stdout, "psArray", "Remove null item from array");
+    if( psArrayRemove(psArr,NULL) ) {
+        psError(PS_ERR_UNKNOWN,true,"Remove null item from array",true);
+        return 105;
+    }
+    printFooter(stdout,"psArray","Remove null item from array",true);
+
+    // Test J - Free void pointer array
+    printPositiveTestHeader(stdout, "psArray", "Free void pointer array");
+    psFree(psArr);
+    for(psS32 i = 0; i < 10; i++) {
+        psFree(mySt[i]);
+    }
+    if( psMemCheckLeaks(0, NULL, stdout, false) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 110;
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 111;
+    }
+    printFooter(stdout, "psArray" ,"Free void pointer array", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psArray01.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psArray01.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psArray01.c	(revision 3057)
@@ -0,0 +1,132 @@
+/** @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)  Sort data in array
+ *     D)  Attempt to sort data in invalid array
+ *     E)  Free void pointer array
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-30 01:26:47 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <math.h>
+
+#include "pslib.h"
+#include "psTest.h"
+
+typedef struct
+{
+    psS32 x;
+    float y;
+}
+testStruct;
+
+int testStructCompare(const void **a, const void **b)
+{
+    testStruct* first = (testStruct*)*a;
+    testStruct* second = (testStruct*)*b;
+
+    if(first->x < second->x)
+        return -1;
+    else if (first->x > second->x)
+        return 1;
+    else
+        return 0;
+}
+
+psS32 main(psS32 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(10);
+    if (psArr->nalloc != 10) {
+        psError(PS_ERR_UNKNOWN, true,"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(psS32 i = 0; i < 10; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*(10-i);
+        ts->y = 10.1*(10-i);
+        mySt[i] = ts;
+        psArr->data[i] = ts;
+        psMemIncrRefCounter(ts);
+    }
+
+    for(psS32 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*(10-i)) > 0.01f || fabsf(ts->y - 10.1*(10-i)) > 0.01f) {
+            psError(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
+            return 2;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 10) {
+        psError(PS_ERR_UNKNOWN, true,"Array Size wrong");
+        return 3;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 10) {
+        psError(PS_ERR_UNKNOWN, true,"Array population wrong");
+        return 4;
+    }
+    printFooter(stdout, "psArray", "Add data to void pointer array", true);
+
+    // Test C - Sort data in array
+    printPositiveTestHeader(stdout,"psArray","Sort data in array");
+    psArr = psArraySort(psArr,testStructCompare);
+    for(psS32 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+1)) > 0.01f || fabsf(ts->y - 10.1*(i+1)) > 0.01f) {
+            psError(PS_ERR_UNKNOWN, true,"Couldn't properly get elements from array.");
+            return 5;
+        }
+    }
+    printFooter(stdout,"psArray","Sort data in array",true);
+
+    // Test D - Attempt to sort null array
+    printPositiveTestHeader(stdout,"psArray","Attempt to sort array");
+    psArray* tempArr = psArraySort(NULL,testStructCompare);
+    if(tempArr != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Array sort did not return null when sorting null array");
+        return 6;
+    }
+    printFooter(stdout,"psArray","Attempt to sort array",true);
+
+    // Test E - Free void pointer array
+    printPositiveTestHeader(stdout, "psArray", "Free void pointer array");
+    psFree(psArr);
+    for(psS32 i = 0; i < 10; i++) {
+        psFree(mySt[i]);
+    }
+    if( psMemCheckLeaks(0, NULL, stdout, false) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 110;
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 111;
+    }
+    printFooter(stdout, "psArray" ,"Free void pointer array", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psArray02.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psArray02.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psArray02.c	(revision 3057)
@@ -0,0 +1,128 @@
+/** @file  tst_psImageManip.c
+*
+*  @brief Contains the tests for psImageManip.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-27 21:12:47 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 testArrayAdd( void );
+
+testDescription tests[] = {
+                              {testArrayAdd, 788, "psArrayAdd", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psArray", tests, argc, argv ) );
+}
+
+psS32 testArrayAdd( void )
+{
+    int subtest = 0;
+    float* data;
+    int nalloc = 5;
+    int n = 0;
+    int delta = 5;
+
+    // allocate the array.
+    psArray* arr = psArrayAlloc(nalloc);
+    arr->n = n;
+
+    // test arrayAdd until n == nalloc
+    while (n < nalloc) {
+        data = psAlloc(sizeof(float));
+        arr = psArrayAdd(arr, delta*2, data); // make delta unique versus next delta used.
+
+        subtest++;
+        if (arr->nalloc != nalloc) {
+            psError(PS_ERR_UNKNOWN,true,
+                    "psArrayAdd expanded the psArray unnecessarily.  n=%d",
+                    n);
+            return subtest;
+        }
+
+        subtest++;
+        if (arr->n != ++n) {
+            psError(PS_ERR_UNKNOWN,true,
+                    "psArrayAdd did not increment the size of the psArray. n=%d",
+                    n);
+            return subtest;
+        }
+
+        subtest++;
+        if (arr->data[n-1] != data) {
+            psError(PS_ERR_UNKNOWN,true,
+                    "psArrayAdd didn't set the element to data. n=%d",
+                    n);
+            return subtest;
+        }
+    }
+
+    // now try to add an element when the array is full.
+    data = psAlloc(sizeof(float));
+    arr = psArrayAdd(arr, delta, data);
+
+    // make sure the array was expanded
+    subtest++;
+    if (arr->nalloc != nalloc+delta) {
+        psError(PS_ERR_UNKNOWN,true,
+                "psArrayAdd did not expand the psArray when it was already full."
+                " old nalloc=%d, nalloc=%d, delta=%d",
+                nalloc, arr->nalloc, delta);
+        return subtest;
+    }
+    nalloc = arr->nalloc;
+
+    subtest++;
+    if (arr->n != ++n) {
+        psError(PS_ERR_UNKNOWN,true,
+                "psArrayAdd did not increment psArray.n by 1 after expanding it.");
+        return subtest;
+    }
+
+    subtest++;
+    if (arr->data[n-1] != data) {
+        psError(PS_ERR_UNKNOWN,true,
+                "psArrayAdd didn't set the second element to data.");
+        return subtest;
+    }
+
+    // make the array full again (operation tested already)
+    while (arr->n < arr->nalloc) {
+        data = psAlloc(sizeof(float));
+        arr = psArrayAdd(arr, 0, data);
+    }
+    nalloc = arr->nalloc;
+    n = arr->n;
+
+    // now add to full array with delta = 0; verify that the array is
+    // expanded by 10
+    data = psAlloc(sizeof(float));
+    arr = psArrayAdd(arr, 0, data);
+
+    subtest++;
+    if (arr->nalloc != nalloc+10) {
+        psError(PS_ERR_UNKNOWN,true,
+                "psArrayAdd did not expand the psArray by 10 when delta < 1."
+                " old nalloc=%d, nalloc=%d",
+                nalloc, arr->nalloc);
+        return subtest;
+    }
+
+    psFree(arr);
+
+    return 0;  // the value that indicates success is part of the testDescription
+}
+
Index: /branches/rel4/psLib/test/collections/tst_psBitSet.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psBitSet.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psBitSet.c	(revision 3057)
@@ -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.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-27 00:57:33 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+static psS32 testBitSet01a(void);
+static psS32 testBitSet01b(void);
+static psS32 testBitSet01c(void);
+static psS32 testBitSet02(void);
+static psS32 testBitSet03(void);
+static psS32 testBitSet04(void);
+static psS32 testBitSet05(void);
+static psS32 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}
+                          };
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psBitSet", tests, argc, argv ) );
+}
+
+psS32 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;
+}
+
+psS32 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 psS32 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;
+}
+
+psS32 testBitSet02()
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* and = psBitSetAlloc(24);
+    for(psS32 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(and,i);
+        psBool 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(and,i);
+        psBool 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 psS32 testBitSet03(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* or = psBitSetAlloc(24);
+    for(psS32 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(or,i);
+        psBool 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(or,i);
+        psBool 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 psS32 testBitSet04(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* xor = psBitSetAlloc(24);
+    for(psS32 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(xor,i);
+        psBool 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(xor,i);
+        psBool 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 psS32 testBitSet05(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* not = psBitSetAlloc(24);
+    for(psS32 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(not,i);
+        psBool 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(psS32 i=0; i<24; i++) {
+        psBool truth = psBitSetTest(not,i);
+        psBool 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 psS32 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/rel4/psLib/test/collections/tst_psHash00.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash00.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash00.c	(revision 3057)
@@ -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
+psS32 main()
+{
+    psHash *myHashTable = NULL;
+    psS32 testStatus      = true;
+    psS32 i               = 0;
+    psS32 currentId = psMemGetId();
+    psS32 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/collections/tst_psHash01.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash01.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash01.c	(revision 3057)
@@ -0,0 +1,155 @@
+/*****************************************************************************
+    This code will test whether a hash table can be de-allocated successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+psS32 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);
+}
+
+psS32 main()
+{
+    psHash *myHashTable = NULL;
+    psS32 testStatus      = true;
+    psS32 currentId = psMemGetId();
+    ID* id = NULL;
+    ID* replaceId = NULL;
+    psS32 memLeaks        = 0;
+    psBool  retVal = false;
+
+    // Allocate memory for Hash Table
+    printPositiveTestHeader(stdout,"psHash functions","psHashAlloc");
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    if(myHashTable == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Unable to allocate psHash table");
+        return 10;
+    }
+    printFooter(stdout,"psHash functions","psHashAlloc",true);
+
+    // Add items to Hash table
+    id = IdAlloc("IDA");
+    printPositiveTestHeader(stdout,"psHash functions","psHashAdd");
+    retVal = psHashAdd(myHashTable, "ENTRY00", id);
+    psFree(id);
+    if( !retVal) {
+        psError(PS_ERR_UNKNOWN, true, "psHashAdd unable to add ENTRY00");
+        return 1;
+    }
+
+    id = IdAlloc("IDB");
+    retVal = psHashAdd(myHashTable, "ENTRY01", id);
+    psFree(id);
+    if (!retVal) {
+        psError(PS_ERR_UNKNOWN, true, "psHashAdd unable to add ENTRY01");
+        return 2;
+    }
+
+    id = IdAlloc("IDC");
+    retVal = psHashAdd(myHashTable, "ENTRY02", id);
+    psFree(id);
+    if(!retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd unable to add ENTRY02");
+        return 3;
+    }
+
+    id = IdAlloc("IDD");
+    retVal =psHashAdd(myHashTable, "ENTRY03", id);
+    psFree(id);
+    if(!retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd unable to add ENTRY03");
+        return 4;
+    }
+    printFooter(stdout,"psHash functions","psHashAdd",true);
+
+    // Replace item with same key
+    printPositiveTestHeader(stdout,"psHash replace item","psHashAdd");
+    id = IdAlloc("IDE");
+    retVal = psHashAdd(myHashTable,"ENTRY02",id);
+    if(!retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd unable to replace ENTRY02");
+        return 5;
+    }
+    replaceId = psHashLookup(myHashTable,"ENTRY02");
+    if(strcmp(replaceId->name,"IDE") != 0) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd did not replace ENTRY02 with correct item");
+        return 6;
+    }
+    printFooter(stdout,"psHash replace item","psHashAdd",true);
+
+    // Add with NULL hash table specified
+    printNegativeTestHeader(stdout,"psHashAdd","NULL hash table","Hash table can not be NULL.",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashAdd with null table");
+    retVal = psHashAdd(NULL,"ENTRY04",id);
+    if(retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd added entry to NULL hash table.");
+        return 20;
+    }
+    printFooter(stdout,"psHashAdd","NULL hash table",true);
+
+    // Add with key to valid hash table NULL
+    printNegativeTestHeader(stdout,"psHashAdd","NULL key","Hash key can not be NULL.",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashAdd with null key");
+    retVal = psHashAdd(myHashTable,NULL,id);
+    if(retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd added entry to hash table with NULL key.");
+        return 21;
+    }
+    printFooter(stdout,"psHashAdd","NULL hash key",true);
+
+    // Add NULL hash data to valid table and key
+    printNegativeTestHeader(stdout,"psHashAdd","NULL hash data","Hash data can not be NULL.",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashAdd with null data");
+    retVal = psHashAdd(myHashTable,"ENTRY04",NULL);
+    if(retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashAdd added entry to hash table with NULL data.");
+        return 22;
+    }
+    printFooter(stdout,"psHashAdd","NULL hash data",true);
+
+    // Free hash table
+    printPositiveTestHeader(stdout,"psHash functions","psHashFree");
+    psFree(id);
+
+    psFree(myHashTable);
+
+    if (imGlobal != 5) {
+        fprintf(stderr, "%s: only (%d/4) entries were freed",
+                __func__, imGlobal);
+        testStatus = false;
+    }
+
+    printFooter(stdout,"psHash functions","psHashFree()",testStatus);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (memLeaks != 0) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/collections/tst_psHash02.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash02.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash02.c	(revision 3057)
@@ -0,0 +1,113 @@
+/*****************************************************************************
+    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
+psS32 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);
+}
+
+psS32 main()
+{
+    psHash *myHashTable = NULL;
+    psS32 testStatus      = true;
+    psS32 i               = 0;
+    ID *id = NULL;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks        = 0;
+
+    printPositiveTestHeader(stdout,"psHash functions","psHashLookup");
+
+    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]);
+            return 1;
+        }
+        i++;
+    }
+    printFooter(stdout,"psHash functions","psHashLookup",true);
+
+    // Use an invalid key in the hash table: verify no item is returned
+    printNegativeTestHeader(stdout,"psHashLookup","Invalid key","Key is not found in the table",0);
+    id = psHashLookup(myHashTable, "BogusKey");
+    if (id != NULL) {
+        fprintf(stderr, "%s: Hash table entry for key %s was not NULL.\n",
+                __func__, "BogusKey");
+        return 2;
+    }
+    printFooter(stdout,"psHashLookup","Invalid key",true);
+
+    // Lookup with null table
+    printNegativeTestHeader(stdout,"psHashLookup","NULL table","Can not lookup with NULL table",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashLookup with null table");
+    id = psHashLookup(NULL,"ENTRY01");
+    if (id != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psHashLookup retrieved an entry from NULL hash table.");
+        return 3;
+    }
+    printFooter(stdout,"psHashLookup","NULL table",true);
+
+    // Lookup with null key
+    printNegativeTestHeader(stdout,"psHashLookup","NULL key","Can not lookup with NULL key.",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashLookup with null key");
+    id = psHashLookup(myHashTable,NULL);
+    if (id != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psHashLookup retrieved an entry with NULL key.");
+        return 4;
+    }
+    printFooter(stdout,"psHashLookup","NULL key",true);
+
+    psFree(myHashTable);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/collections/tst_psHash03.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash03.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash03.c	(revision 3057)
@@ -0,0 +1,142 @@
+/*****************************************************************************
+    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
+psS32 imGlobal = 0;
+psS32 currentId = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static void IdFree(ID *id);
+
+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);
+}
+
+psS32 main()
+{
+    psHash *myHashTable = NULL;
+    psS32 testStatus      = true;
+    psS32 i               = 0;
+    psS32 TotalKeys       = 0;
+    psBool retVal         = false;
+    ID *id = NULL;
+    ID *ids[4];
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    psS32 memLeaks        = 0;
+
+    currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,"psHash functions","psHashRemove");
+
+    // Add items to hash table
+    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;
+
+    // Verify items which were just add to hash table
+    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]);
+            return 1;
+        }
+        i--;
+    }
+
+    // Remove each item from the table and verify item is no longer in the list
+    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__);
+            return 2;
+        }
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (id != NULL) {
+            fprintf(stderr, "%s: Hash table entry for key %s not removed.\n",
+                    __func__, "IDA");
+            return 3;
+        }
+        i++;
+    }
+    printFooter(stdout,"psHash functions","psHashRemove()",true);
+
+    // Use an invalid key in the hash table: verify false is returned
+    printNegativeTestHeader(stdout,"psHashRemove","Invalid key","Key is not found in table",0);
+    if (psHashRemove(myHashTable,"BogusKey") ) {
+        psError(PS_ERR_UNKNOWN,true,"psHashRemove removed an entry with a bogus key.");
+        return 4;
+    }
+    printFooter(stdout,"psHashRemove","Invalid key",true);
+
+    // Remove with null table
+    printNegativeTestHeader(stdout,"psHashRemove","NULL table","Can not remove with NULL table",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashRemove with null table");
+    retVal = psHashRemove(NULL,"ENTRY02");
+    if (retVal) {
+        psError(PS_ERR_UNKNOWN,true,"psHashRemove removed an entry from NULL hash table.");
+        return 5;
+    }
+    printFooter(stdout,"psHashRemove","NULL table",true);
+
+    // Remove with null key
+    printNegativeTestHeader(stdout,"psHashRemove","NULL key","Can not remove with NULL key",0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message: psHashRemove with null key");
+    if (psHashRemove(myHashTable,NULL) ) {
+        psError(PS_ERR_UNKNOWN,true,"psHashRemove removed an entry from NULL key");
+        return 6;
+    }
+    printFooter(stdout,"psHashRemove","NULL key",true);
+
+    psFree(myHashTable);
+    for(i=0; i<(TotalKeys+1); i++) {
+        psFree(ids[i]);
+    }
+    memLeaks = psMemCheckLeaks(currentId,NULL,stdout,false);
+    if (memLeaks != 0) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(true);
+
+    return (!testStatus);
+}
+
Index: /branches/rel4/psLib/test/collections/tst_psHash04.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash04.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash04.c	(revision 3057)
@@ -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
+psS32 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);
+}
+
+psS32 main()
+{
+    psHash *myHashTable = NULL;
+    psS32 testStatus      = true;
+    psS32 i               = 0;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    psS32 currentId = psMemGetId();
+    psS32 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;
+    }
+    printFooter(stdout,"psHash functions","psHashKeyList()",testStatus);
+    psFree(myLinkList);
+
+    printNegativeTestHeader(stdout,"psHashKeyList","NULL table","Can not lookup with NULL table",0);
+    myLinkList = psHashKeyList(NULL);
+    if(myLinkList != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psHashKeyList retrieved a key list from a NULL table.");
+        return 1;
+    }
+    printFooter(stdout,"psHashKeyList","NULL table",true);
+
+    psFree(myHashTable);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (memLeaks != 0) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /branches/rel4/psLib/test/collections/tst_psHash05.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psHash05.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psHash05.c	(revision 3057)
@@ -0,0 +1,172 @@
+/** @file  tst_psHash05.c
+*
+*  @brief Contains the tests for psHash.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-03 20:28:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 hashToArray( void );
+
+testDescription tests[] = {
+                              {hashToArray, 789, "psHashToArray", 0, false},
+                              {NULL}
+                          };
+
+static void printIntArray(char* name, psArray* arr)
+{
+    if (arr == NULL) {
+        printf("%s = NULL\n",name);
+        return;
+    }
+
+    printf("%s = {",name);
+    for (int i = 0; i < arr->n; i++) {
+        if (arr->data[i] == NULL) {
+            printf("NULL");
+        } else {
+            printf("%d",*(int*)arr->data[i]);
+        }
+        if (i != arr->n-1) {
+            printf(",");
+        }
+    }
+    printf("}");
+}
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psHash", tests, argc, argv ) );
+}
+
+psS32 hashToArray( void )
+{
+    int testNum = 0;
+    psArray* array;
+    #define BUCKETS 10
+
+    psHash* hash = psHashAlloc(BUCKETS);
+    char key[2] = "A";
+    bool found[BUCKETS];
+
+    for (int i = 0; i < BUCKETS; i++) {
+
+        array = psHashToArray(hash);
+
+        // return non-null?
+        testNum++;
+        if (array == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to create an array from a psHash of %d elements.",
+                    i);
+            return testNum;
+        }
+
+        // the size correct
+        testNum++;
+        if (array->n != i) {
+            printIntArray("array",array);
+            psError(PS_ERR_UNKNOWN, false,
+                    "psHashToArray created a psArray of %d elements from a psHash of %d elements.",
+                    array->n, i);
+            return testNum;
+        }
+
+        // the values correct?
+
+        // zero out the found boolean vector
+        for (int j = 0; j < i; j++) {
+            found[j] = false;
+        }
+
+        // check if all the items in array are valid
+        for (int k = 0; k < array->n; k++) {
+            int* item = array->data[k];
+
+            testNum++;
+            if (item == NULL) {
+                printIntArray("array",array);
+                psError(PS_ERR_UNKNOWN, true,
+                        "The array position %d was NULL.",
+                        k);
+                return testNum;
+            }
+
+            testNum++;
+            if (*item < 0 || *item >= BUCKETS) {
+                printIntArray("array",array);
+                psError(PS_ERR_UNKNOWN, true,
+                        "The array position %d was invalid (%d).",
+                        k,*item);
+                return testNum;
+            }
+
+            testNum++;
+            if (found[*item]) {
+                printIntArray("array",array);
+                psError(PS_ERR_UNKNOWN, true,
+                        "The array position %d was a duplicate (%d).",
+                        k,*item);
+                return testNum;
+            }
+
+            testNum++;
+            if (psMemGetRefCounter(item) != 2) {
+                printIntArray("array",array);
+                psError(PS_ERR_UNKNOWN, true,
+                        "The array position %d was not properly reference counted (%d).",
+                        k,psMemGetRefCounter(item));
+                return testNum;
+            }
+
+            found[*item] = true;
+        }
+
+        // check that all the items in psHash was found
+        for (int j = 0; j < i; j++) {
+            testNum++;
+            if (! found[j]) {
+                printIntArray("array",array);
+                psError(PS_ERR_UNKNOWN, true,
+                        "Item %d not found in array.",
+                        j);
+                return testNum;
+            }
+        }
+
+        psFree(array);
+
+        // add one element
+        int* value = psAlloc(sizeof(int));
+        *value = i;
+        psHashAdd(hash, key, value);
+        *key += 1; // increment the key value
+
+        psFree(value);
+    }
+
+    psFree(hash);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    array = psHashToArray(NULL);
+    testNum++;
+    if (array != NULL) {
+        printIntArray("array",array);
+        psError(PS_ERR_UNKNOWN, false,
+                "psHashToArray returned non-null psArray given a null psHash.");
+        return testNum;
+    }
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/collections/tst_psList.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psList.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psList.c	(revision 3057)
@@ -0,0 +1,1028 @@
+/** @file  tst_psList.c
+ *
+ *  @brief Contains the tests for psList.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-11 01:24:15 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+
+void printListInt(psList* list);
+
+
+static psS32 testListAlloc(void);
+static psS32 testListAdd(void);
+static psS32 testListGet(void);
+static psS32 testListRemove(void);
+static psS32 testListConvert(void);
+static psS32 testListIterator(void);
+static psS32 testListFree(void);
+static psS32 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}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psList",tests,argc,argv) ) {
+        psError(PS_ERR_UNKNOWN,true,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+psS32 testListAlloc(void)
+{
+    psList* list;
+    psS32 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(PS_ERR_UNKNOWN, true,"psListAlloc failed to return a list.");
+        return 1;
+    }
+
+    if (list->head != NULL || list->tail != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"head and/or tail was not NULL for empty list.");
+        return 2;
+    }
+
+    if (list->size != 0) {
+        psError(PS_ERR_UNKNOWN, true,"size of list wasn't zero for empty list.");
+        return 3;
+    }
+
+    psFree(list);
+
+    list = psListAlloc(data);
+    if (list == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psListAlloc failed to return a list.");
+        return 4;
+    }
+
+    if (list->head == NULL || list->tail == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"head and/or tail was NULL for one-element new list.");
+        return 5;
+    }
+
+    if (list->head->data != data || list->tail->data != data) {
+        psError(PS_ERR_UNKNOWN, true,"head and/or tail didn't point to data's node for one-element new list.");
+        return 6;
+    }
+
+    if (list->size != 1) {
+        psError(PS_ERR_UNKNOWN, true,"size of list wasn't correctly set for new, one-element list.");
+        return 7;
+    }
+
+    ref = psMemGetRefCounter(data);
+    if (ref != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psList didn't increment reference count of data (%d.",ref);
+        return 8;
+    }
+
+
+    psFree(list);
+
+    psFree(data);
+
+    return 0;
+}
+
+psS32 testListAdd(void)
+{
+    psList* list = NULL;
+    psS32* 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(psS32));
+    *data = 1;
+
+    //  1. list is NULL (error)
+    if (psListAdd(NULL,PS_LIST_HEAD,data)) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd was given a NULL list, but returned a true/success.");
+        return 1;
+    }
+
+    list = psListAlloc(data);
+    psFree(data);
+    if (list->size != 1) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psListAdd successfully added a NULL data item?");
+        return 40;
+    }
+    if ( list->size != 1) {
+        psError(PS_ERR_UNKNOWN, true,"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(psS32));
+    *data = 2;
+    if ( ! psListAdd(list,PS_LIST_HEAD,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add a data item to head.");
+        return 21;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+
+    // verify that the size incremented
+    if (list->size != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the size by one");
+        return 4;
+    }
+
+    // verify that the head is the inserted data item
+    if (*(psS32*)list->head->data != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd with PS_LIST_HEAD didn't insert at the head.");
+        return 5;
+    }
+
+    data = psAlloc(sizeof(psS32));
+    *data = 3;
+    if ( ! psListAdd(list,PS_LIST_TAIL,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add a data item to tail.");
+        return 21;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 22;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 3) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the size by 1");
+        return 6;
+    }
+
+    // verify that the head is still the same
+    if (*(psS32*)list->head->data != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd with PS_LIST_TAIL modified the head.");
+        return 7;
+    }
+
+    // verify that the tail is the data item inserted
+    if (*(psS32*)list->tail->data != 3) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd with PS_LIST_TAIL didn't insert at the tail.");
+        return 8;
+    }
+
+    // 4. where is not PS_LIST_* but <0
+
+    data = psAlloc(sizeof(psS32));
+    *data = 4;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with invalid insert location");
+
+    if ( psListAdd(list,-10,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd successfully added data to a -10 position?");
+        return 30;
+    }
+    if (psMemGetRefCounter(data) != 1) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd incremented the data reference count.");
+        return 24;
+    }
+    psFree(data);
+    // verify that the size wasn't incremented
+    if (list->size != 3) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't insert to head when where was invalid.");
+        return 9;
+    }
+
+    // 5. where is >0
+    data = psAlloc(sizeof(psS32));
+    *data = 5;
+
+    if ( ! psListAdd(list,1,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add data to 1 position.");
+        return 30;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 25;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 4 || *(psS32*)list->head->next->data != 5) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't insert to position #1.");
+        return 10;
+    }
+
+    data = psAlloc(sizeof(psS32));
+    *data = 6;
+    if ( ! psListAdd(list,3,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add data to 4 position.");
+        return 31;
+    }
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 26;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 5  || *(psS32 *)list->head->next->next->next->data != 6) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't insert to position #4.");
+        return 50;
+    }
+
+    data = psAlloc(sizeof(psS32));
+    *data = 7;
+    if ( ! psListAdd(list,2,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add data to 2 position.");
+        return 32;
+    }
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 28;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 6  || *(psS32 *)list->head->next->next->data != 7) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't insert to position #2.");
+        return 11;
+    }
+
+    data = psAlloc(sizeof(psS32));
+    *data = 7;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a warning.");
+
+    if ( ! psListAdd(list,9,data) ) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd failed to add data to a 9 position?");
+        return 30;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't increment the data reference count.");
+        return 29;
+    }
+
+    psFree(data);
+
+    // verify that the size incremented
+    if (list->size != 7) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"psListAdd didn't insert to position #9.");
+        return 12;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+void printListInt(psList* list)
+{
+    psS32* data = NULL;
+    psBool first = true;
+
+    psListIterator* iter = psListIteratorAlloc(list,PS_LIST_HEAD);
+
+    while ( (data=(psS32*)psListGetNext(iter)) != NULL ) {
+        if (!first) {
+            printf(", %d",*(psS32*)data);
+        } else {
+            printf("%d",*(psS32*)data);
+            first = false;
+        }
+    }
+
+    printf(".\n");
+}
+
+
+psS32 testListGet(void)
+{
+    psList* list = NULL;
+    psS32* 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(PS_ERR_UNKNOWN, true,"psListGet didn't return NULL given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    data = psAlloc(sizeof(psS32));
+    *data = 0;
+    list = psListAlloc(data);
+    psFree(data);
+
+    data = psAlloc(sizeof(psS32));
+    *data = 1;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    data = psAlloc(sizeof(psS32));
+    *data = 2;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    data = psAlloc(sizeof(psS32));
+    *data = 3;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    //  2. which>0 and which<list.n.
+    data = (psS32*)psListGet(list,3);
+    if (data == NULL || *data != 3) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=3");
+        return 2;
+    }
+    data = (psS32*)psListGet(list,1);
+    if (data == NULL || *data != 1) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=1");
+        return 3;
+    }
+
+    //  3. which>=list.n.
+    data = (psS32*)psListGet(list,5);
+    if (data != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=5");
+        return 4;
+    }
+    data = (psS32*)psListGet(list,4);
+    if (data != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=4");
+        return 5;
+    }
+
+    //  4. which=PS_LIST_HEAD
+    data = (psS32*)psListGet(list,PS_LIST_HEAD);
+    if (data == NULL || *data != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=PS_LIST_HEAD");
+        return 6;
+    }
+
+    //  6. which=PS_LIST_TAIL
+    data = (psS32*)psListGet(list,PS_LIST_TAIL);
+    if (data == NULL || *data != 3) {
+        psError(PS_ERR_UNKNOWN, true,"psListGet failed with which=PS_LIST_TAIL");
+        return 8;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+psS32 testListRemove(void)
+{
+    psList* list = NULL;
+    psS32* data;
+    int items = 15;
+
+    /*
+        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)) {
+        psError(PS_ERR_UNKNOWN, true,"psListRemove didn't return false given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    list = psListAlloc(NULL);
+
+    for (psS32 lcv=0;lcv<items;lcv++) {
+        data = psAlloc(sizeof(psS32));
+        *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)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove PS_LIST_HEAD");
+        return 1;
+    }
+
+    if (list->size != --items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't decrement size properly to %d.",items);
+        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)) ||
+            (psListGet(list,PS_LIST_TAIL) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove PS_LIST_TAIL");
+        return 1;
+    }
+
+    if (list->size != --items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't decrement size properly to %d.",items);
+        return 1;
+    }
+
+    // 6. psListRemoveData where data=NULL (error)
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if (psListRemoveData(list,NULL)) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"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 ( (! psListRemoveData(list,data)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_HEAD");
+        return 1;
+    }
+
+    if (list->size != --items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't decrement size properly to %d.",items);
+        return 1;
+    }
+
+    data = psListGet(list,PS_LIST_TAIL);
+    if ( (!psListRemoveData(list,data)) ||
+            (psListGet(list,PS_LIST_TAIL) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_TAIL");
+        return 1;
+    }
+
+    if (list->size != --items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't decrement size properly to %d.",items);
+        return 1;
+    }
+
+    data = psListGet(list,1);
+    if ( (! psListRemoveData(list,data))||
+            (psListGet(list,1) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove data @ which=1");
+        return 1;
+    }
+
+    if (list->size != --items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't decrement size properly to %d.",items);
+        return 1;
+    }
+
+    // 8. data!=NULL and data!=any element in list
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if ( psListRemoveData(list,data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"removed something for PS_LIST_UNKNOWN with previously removed item");
+        return 1;
+    }
+
+    if (list->size != items) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"size not %d, as expected.",items);
+        return 1;
+    }
+
+    // clear out the list
+    while (items > 1) {
+        psListRemove(list,PS_LIST_HEAD);
+        items--;
+    }
+
+    data = psListGet(list,PS_LIST_HEAD);
+    if ( (! psListRemove(list,PS_LIST_HEAD)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Failed to remove last element");
+        return 1;
+    }
+
+    if (list->size != 0) {
+        printListInt(list);
+        psError(PS_ERR_UNKNOWN, true,"Didn't remove all the elements.");
+        return 1;
+    }
+
+    psFree(list);
+
+    return 0;
+
+}
+
+psS32 testListConvert(void)
+{
+
+    psList* list = NULL;
+    psArray* arr = NULL;
+    psS32* data;
+
+    /*
+        array=psListToArray(list) shall take each element of the list, increment
+        their reference, and insert them into the returned fresh psPtr array.
+        The list shall not be changed, except for the element reference increment.
+    */
+
+    // test dlist -> array
+
+    // create a list
+    list = psListAlloc(NULL);
+    for (psS32 lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(psS32));
+        *data = lcv;
+        psListAdd(list,PS_LIST_TAIL,data);
+        psMemDecrRefCounter(data);
+    }
+
+    arr = psListToArray(list);
+
+    if (arr->n != 15 || list->size != 15) {
+        psError(PS_ERR_UNKNOWN, true,"The created array didn't have the proper size");
+        return 1;
+    }
+    for (psS32 i=0;i<arr->n;i++) {
+        if (i != *(psS32*)arr->data[i]) {
+            psError(PS_ERR_UNKNOWN, true,"Element %d of array is incorrect (%d).",
+                    i,*(psS32*)arr->data[i]);
+            return 1;
+        }
+        if (i != *(psS32*)psListGet(list,i)) {
+            psError(PS_ERR_UNKNOWN, true,"Element %d of list is incorrect (%d).",
+                    i,*(psS32*)arr->data[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(arr->data[i]) != 2) {
+            psError(PS_ERR_UNKNOWN, true,"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 (psS32 lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(psS32));
+        *data = lcv;
+        arr->data[lcv] = data;
+    }
+
+    list = psArrayToList(arr);
+
+    if (arr->n != 15 || list->size != 15) {
+        psError(PS_ERR_UNKNOWN, true,"The created array didn't have the proper size");
+        return 1;
+    }
+    for (psS32 i=0;i<arr->n;i++) {
+        if (i != *(psS32*)arr->data[i]) {
+            psError(PS_ERR_UNKNOWN, true,"Element %d of array is incorrect (%d).",
+                    i,*(psS32*)arr->data[i]);
+            return 1;
+        }
+        if (i != *(psS32*)psListGet(list,i)) {
+            psError(PS_ERR_UNKNOWN, true,"Element %d of list is incorrect (%d).",
+                    i,*(psS32*)arr->data[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(arr->data[i]) != 2) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psListToArray didn't return NULL when given NULL");
+        return 1;
+    }
+
+    list = psArrayToList(NULL);
+    if (list != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psArrayToList didn't create an empty array from an "
+                "empty list.");
+        return 1;
+    }
+    psFree(arr);
+    psFree(list);
+
+    return 0;
+}
+
+psS32 testListIterator(void)
+{
+    psList* list = NULL;
+    psS32* 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 (psS32 lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(psS32));
+        *data = lcv;
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+    }
+
+    psListIterator* iter = psListIteratorAlloc(list,PS_LIST_HEAD);
+    if (iter == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"Failed to make an iterator.");
+        return 22;
+    }
+
+    // 1. output error message and do nothing if iterator=NULL
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with "
+             "'Unexpected null pointer'");
+    psListIteratorSet(NULL,PS_LIST_HEAD);
+    if (psListIteratorSet(NULL,PS_LIST_HEAD)) {
+        psError(PS_ERR_UNKNOWN, true,"Success while setting position of a NULL iterator?");
+        return 23;
+    }
+
+
+    // 3. set list.cursor to list.tail if where=PS_LIST_TAIL
+
+    if (!psListIteratorSet(iter,PS_LIST_TAIL) ||
+            *(psS32*)iter->cursor->data != 14 ||
+            iter->index != 14) {
+        psError(PS_ERR_UNKNOWN, true,"Didn't successfully move cursor to tail.");
+        return 1;
+    }
+
+    // 2. set list.cursor to list.head if where=PS_LIST_HEAD
+    if (!psListIteratorSet(iter,PS_LIST_HEAD) ||
+            *(psS32*)iter->cursor->data != 0 ||
+            iter->index != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Didn't successfully move cursor to head.");
+        return 2;
+    }
+
+    // test psListGetPrevious/Next
+    if (*(psS32*)psListGetNext(iter) != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetNext didn't move cursor to next.");
+        return 8;
+    }
+    if (*(psS32*)psListGetNext(iter) != 1) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetNext didn't move cursor to next.");
+        return 9;
+    }
+    if (*(psS32*)psListGetNext(iter) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetNext didn't move cursor to next.");
+        return 10;
+    }
+
+    if (*(psS32*)psListGetPrevious(iter) != 3) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetPrevious didn't move cursor to previous.");
+        return 11;
+    }
+    if (*(psS32*)psListGetPrevious(iter) != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetPrevious didn't move cursor to previous.");
+        return 12;
+    }
+    if (*(psS32*)psListGetPrevious(iter) != 1) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetPrevious didn't move cursor to previous..");
+        return 13;
+    }
+    if (*(psS32*)psListGetPrevious(iter) != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetPrevious didn't move cursor to previous..");
+        return 14;
+    }
+    if (psListGetPrevious(iter) != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetPrevious moved cursor beyond head.");
+        return 15;
+    }
+
+    psListIteratorSet(iter,PS_LIST_TAIL); // works according to an above test
+    if (*(psS32*)psListGetNext(iter) != 14) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetNext moved cursor beyond tail.");
+        return 16;
+    }
+    if (psListGetNext(iter) != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psListGetNext moved cursor beyond tail.");
+        return 17;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+psS32 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 (psS32 lcv=0;lcv<15;lcv++) {
+        data[lcv] = psAlloc(sizeof(psS32));
+        *data[lcv] = lcv;
+        psListAdd(list,PS_LIST_TAIL,data[lcv]);
+        if (psMemGetRefCounter(data[lcv]) != 2) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 (psS32 i=0;i<15;i++) {
+        if (psMemGetRefCounter(data[i]) != 1) {
+            psError(PS_ERR_UNKNOWN, true,"pslistFree didn't decrement the data item's reference counter");
+            return 3;
+        }
+        psFree(data[i]);
+    }
+
+    return 0;
+}
+
+psS32 testListSort(void)
+{
+    psList* list;
+    psListIterator* iter;
+    float* fValue;
+    psU32* uValue;
+
+    list = psListAlloc(NULL);
+
+    for (psS32 lcv=0;lcv<15;lcv++) {
+        float* data = psAlloc(sizeof(psS32));
+        if (lcv < 7) {
+            *data = 13-lcv*2;
+        } else {
+            *data = lcv*2-12;
+        }
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+
+    }
+
+    printf("original list = [");
+    iter = psListIteratorAlloc(list,PS_LIST_HEAD);
+    while( (fValue=psListGetNext(iter)) != NULL ) {
+        printf(" %.1f",*fValue);
+    }
+    printf(" ]\n");
+
+    list = psListSort(list,psCompareF32Ptr);
+
+    printf("sorted list = [");
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    while( (fValue=psListGetNext(iter)) != NULL ) {
+        printf(" %.1f",*fValue);
+    }
+    printf(" ]\n");
+
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    float* prevFValue = psListGetNext(iter);
+    while( (fValue=psListGetNext(iter)) != NULL ) {
+        if (*prevFValue > *fValue) {
+            psError(PS_ERR_UNKNOWN, true,"Hey, the list wasn't sorted!?");
+            return 1;
+        }
+    }
+
+    list = psListSort(list,psCompareDescendingF32Ptr);
+
+    printf("descending sort list = [");
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    while( (fValue=psListGetNext(iter)) != NULL ) {
+        printf(" %.1f",*fValue);
+    }
+    printf(" ]\n");
+
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    prevFValue = psListGetNext(iter);
+    while( (fValue=psListGetNext(iter)) != NULL ) {
+        if (*prevFValue < *fValue) {
+            psError(PS_ERR_UNKNOWN, true,"Hey, the list wasn't sorted!?");
+            return 2;
+        }
+    }
+
+    psFree(list);
+
+    /********** OK, now do the same thing with ints. *************/
+
+    list = psListAlloc(NULL);
+
+    for (psS32 lcv=0;lcv<15;lcv++) {
+        psU32* data = psAlloc(sizeof(psS32));
+        if (lcv < 7) {
+            *data = 13-lcv*2;
+        } else {
+            *data = lcv*2-12;
+        }
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+
+    }
+
+    printf("original list = [");
+    iter = psListIteratorAlloc(list,PS_LIST_HEAD);
+    while( (uValue=psListGetNext(iter)) != NULL ) {
+        printf(" %d",*uValue);
+    }
+    printf(" ]\n");
+
+    list = psListSort(list,psCompareU32Ptr);
+
+    printf("sorted list = [");
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    while( (uValue=psListGetNext(iter)) != NULL ) {
+        printf(" %d",*uValue);
+    }
+    printf(" ]\n");
+
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    psU32* prevUValue = psListGetNext(iter);
+    while( (uValue=psListGetNext(iter)) != NULL ) {
+        if (*prevUValue > *uValue) {
+            psError(PS_ERR_UNKNOWN, true,"Hey, the list wasn't sorted!?");
+            return 3;
+        }
+    }
+
+    list = psListSort(list,psCompareDescendingU32Ptr);
+
+    printf("descending sort list = [");
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    while( (uValue=psListGetNext(iter)) != NULL ) {
+        printf(" %d",*uValue);
+    }
+    printf(" ]\n");
+
+    psListIteratorSet(iter,PS_LIST_HEAD);
+    prevUValue = psListGetNext(iter);
+    while( (uValue=psListGetNext(iter)) != NULL ) {
+        if (*prevUValue < *uValue) {
+            psError(PS_ERR_UNKNOWN, true,"Hey, the list wasn't sorted!?");
+            return 4;
+        }
+    }
+
+    psFree(list);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psMetadataIO.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadataIO.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadataIO.c	(revision 3057)
@@ -0,0 +1,171 @@
+/** @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.6 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 02:50:15 $
+*
+*  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 printMetadata(psMetadata *metadata);
+static void printMetadataList(psList *metadataItemList, char* spaces);
+static void printMetadataTable(psHash *mdTable);
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list, " ");
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+static void printMetadataList(psList *metadataItemList, char* spaces)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListIterator* iter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD);
+
+    while ( (entryChild=psListGetNext(iter)) != NULL) {
+        printMetadataItem(entryChild, spaces);
+    }
+
+    psFree(iter);
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    psS32 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 printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key pType: %d  ", metadataItem->pType);
+    printf("Key mdType: %d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->data.V && metadataItem->type==PS_META_LIST) {
+        printMetadataList(metadataItem->data.V, "    ");
+    }
+}
+
+
+psS32 main(psS32 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;
+    psU32 failedLines1 = 0;
+    metadata1 = psMetadataParseConfig(metadata1, &failedLines1, "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;
+    psS32 failedLines2 = 0;
+    metadata2 = psMetadataParseConfig(metadata2, &failedLines2, "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();
+    psS32 failedLines3 = 0;
+    metadata3 = psMetadataParseConfig(metadata3, &failedLines3, "test.config", true);
+    printf("Failed lines: %d Expected: 6 ", 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, &failedLines1, 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, &failedLines1, "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);
+    if(psMemCheckLeaks(0, NULL, stdout,false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leak detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/collections/tst_psMetadata_01.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_01.c	(revision 3057)
@@ -0,0 +1,268 @@
+/** @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 - Read named hdr w/ invalid extnum
+*     Test K - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.17 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 02:50:15 $
+*
+*  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 printMetadata(psMetadata *metadata);
+static void printMetadataList(psList *metadataItemList, char* spaces);
+static void printMetadataTable(psHash *mdTable);
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list, " ");
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+static void printMetadataList(psList *metadataItemList, char* spaces)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListIterator* iter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD);
+
+    while ( (entryChild=psListGetNext(iter)) != NULL) {
+        printMetadataItem(entryChild, spaces);
+    }
+
+    psFree(iter);
+
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    psS32 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 printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key pType: %d  ", metadataItem->pType);
+    printf("Key mdType: %d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->data.V && metadataItem->type==PS_META_LIST) {
+        printMetadataList(metadataItem->data.V, "    ");
+    }
+}
+
+
+psS32 main(psS32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataReadHeader did not return null invalid extname give.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use bad extName", true);
+
+
+    // Test J - Read named hdr w/ invalid extnum
+    printNegativeTestHeader(stdout, "psMetadata", "Test J - Read named hdr w/ invalid extnum",
+                            "If extName specified, extNum should be -1.", 0);
+    metadata1 = psMetadataReadHeader(NULL, NULL, 0, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataReadHeader did not return null w/ valid extname, invalid extnum");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test J - Read named hdr w/ invalid extnum", true);
+
+
+    // Test K - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test K - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    if(psMemCheckLeaks(0, NULL, stdout,false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test K - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psMetadata_02.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_02.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_02.c	(revision 3057)
@@ -0,0 +1,151 @@
+/** @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.9 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_F32, PS_META_PRIMITIVE, "I am a single precision floating point", 222.222);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double precision floating point", 333.333);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_PTR, 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_TYPE_PTR, PS_META_STR, "I am a string", "HELLO WORLD");
+    if (badItem != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"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_TYPE_PTR, PS_META_NTYPE, "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);
+    if(psMemCheckLeaks(0, NULL, stdout,false) ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/collections/tst_psMetadata_03.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_03.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_03.c	(revision 3057)
@@ -0,0 +1,248 @@
+/** @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 - Attempt to add item to an invalid metadata structure
+*     Test H - Attempt to add item to an invalid metadata structure
+*     Test I - Attempt to add item with a null name
+*     Test J - Attempt to add item to an invalid metadata structure
+*     Test K - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.11 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    errItem = psMetadataItemAlloc("errItem", PS_TYPE_S32, PS_META_PRIMITIVE, "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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by name.");
+        return 10;
+    }
+    if(!psMetadataAdd(metadata,PS_LIST_HEAD,"myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am S32 integer",77)) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by name.");
+        return 11;
+    }
+    if (!psMetadataRemove(metadata, 0, "myItem1")) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return true when removing by name.");
+        return 12;
+    }
+    if (!psMetadataRemove(metadata, 0, "myItem2")) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by index.");
+        return 14;
+    }
+    if ( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am S32 integer",88) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return true when adding by index.");
+        return 15;
+    }
+    if( ! psMetadataRemove(metadata, 0, NULL) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return true when removing by index.");
+        return 16;
+    }
+    if ( ! psMetadataRemove(metadata, 0, NULL ) ) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 G - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test G - 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 21;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return false w/ invalid metadata struct w/o hash table.");
+        return 31;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test G - Attempt to add item to invalid metadata w/o hash table", 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 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o link list.");
+        return 22;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataRemove did not return false w/ invalid metadata struct w/o link list.");
+        return 32;
+    }
+    errMetadata->list = mdList;
+    printFooter(stdout,"psMetadata","Test H - Attempt to add item to invalid metadata w/o link list", true);
+
+    // Test I - Attempt to add item with a null name
+    printNegativeTestHeader(stdout,"psMetadata","Test I - 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(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false with item with null name.");
+        return 23;
+    }
+    errItem->name = errName;
+    printFooter(stdout,"psMetadata","Test I - Attempt to add item with null name", 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 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_TYPE_S32, PS_META_PRIMITIVE, "Integer",22) ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 24;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test J - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test K - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test K - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(errItem);
+    psFree(errMetadata);
+    if( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test K - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psMetadata_04.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_04.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_04.c	(revision 3057)
@@ -0,0 +1,298 @@
+
+/** @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 - Lookup metadata item and return psS32 value
+*     Test H - Lookup metadata item and return psF64 value
+*     Test I - Lookup metadata item and return psVector pointer
+*     Test J - Attempt to use null metadata
+*     Test K - Attempt to get non-existant metadata item
+*     Test L - Attempt to look up with an invalid metadata object
+*     Test M - Attempt get item  with an invalid metadata object
+*     Test N - Attempt get value of non-existant metadata item
+*     Test O - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.11 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2005-01-13 21:19: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)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psBool status = 0;
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = 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");
+    psVector *vec = psVectorAlloc(5, PS_TYPE_S32);
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_F64, PS_META_PRIMITIVE, "I am a double", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_TYPE_PTR, PS_META_VEC, "I am a vector", vec);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printMetadataItem(item5);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item5, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item6, 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 - Lookup metadata item and return psS32 value
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value");
+    psS32 valueS32 = 0;
+    valueS32 = psMetadataLookupS32(metadata, "myItem2", &status);
+    if(valueS32 != 55) {
+        printf("ERROR: Bad value, %d, Expected 55\n", valueS32);
+        return 15;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 15;
+    }
+    printFooter(stdout, "psMetadata", "Test G - Lookup metadata item and return psS32 value", true);
+
+    // Test H - Lookup metadata item and return psF64 value
+    printPositiveTestHeader(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value");
+    psF64 valueF64 = 0.0;
+    valueF64 = psMetadataLookupF64(metadata, "myItem5", &status);
+    if(fabs(valueF64-3.14) > FLT_EPSILON) {
+        printf("ERROR: Bad value, %g, Expected 3.14\n", valueF64);
+        return 16;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 16;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Lookup metadata item and return psF64 value", true);
+
+    // Test I - Lookup metadata item and return psVector pointer
+    printPositiveTestHeader(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer");
+    psVector *valueVec = NULL;
+    valueVec = psMetadataLookupPtr(metadata, "myItem6", &status);
+    if(valueVec != vec) {
+        printf("ERROR: Bad vector pointer\n");
+        return 17;
+    } else if(! status) {
+        printf("ERROR: Bad status, %d\n", status);
+        return 17;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Lookup metadata item and return psVector pointer", true);
+
+
+    // Test J - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test J - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    item = psMetadataGet(NULL, 0);
+    if ( item != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with null metadata structure");
+        return 18;
+    }
+    printFooter(stdout, "psMetadata", "Test J - Attempt to use null metadata", true);
+
+
+    // Test K - Attempt to get non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test K - Attempt to get non-existant metadata item",
+                            "Couldn't find metadata item with given index. Index: 22", 0);
+    if ( psMetadataGet(metadata, 22) != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psMetadataGet did not return NULL with non-existant metadata item");
+        return 19;
+    }
+    printFooter(stdout, "psMetadata", "Test K - Attempt to get non-existant metadata item", true);
+
+    // Test L - Attempt to look up with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test L - 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(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
+        return 20;
+    }
+    metadata->table = tmpTable;
+    printFooter(stdout, "psMetadata","Test L - Attempt to lookup an invalid metadata object.",true);
+
+    // Test M - Attempt get item with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test M - Attempt 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(PS_ERR_UNKNOWN, true,"psMetadataLookup did not return null for invalid metadata object");
+        return 21;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata","Test M - Attempt to get item with  invalid metadata object",true);
+
+    // Test N - Attempt get psS32 value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test N - Attempt get psS32 value of non-existant metadata item");
+    valueS32 = psMetadataLookupS32(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 22;
+    }
+    printFooter(stdout, "psMetadata","Test N - Attempt get psS32 value of non-existant metadata item",true);
+
+    // Test O - Attempt get psF64 value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test O - Attempt get psF64 value of non-existant metadata item");
+    valueF64 = psMetadataLookupF64(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 23;
+    }
+    printFooter(stdout, "psMetadata","Test O - Attempt get psF64 value of non-existant metadata item",true);
+
+    // Test P - Attempt get psVector value of non-existant metadata item
+    printPositiveTestHeader(stdout, "psMetadata", "Test P - Attempt get psVector value of non-existant metadata item");
+    valueVec = psMetadataLookupPtr(metadata, "myItem22", &status);
+    if(status) {
+        printf("ERROR: Bad status, %d, \n", status);
+        return 24;
+    }
+    printFooter(stdout, "psMetadata","Test P - Attempt get psVector value of non-existant metadata item",true);
+
+    // Test Q - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test Q - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(item6);
+    if ( psMemCheckLeaks(0, NULL, stdout,false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"memory leaks detected.");
+        return 23;
+    }
+    psMemCheckCorruption(0);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 24;
+    }
+    printFooter(stdout, "psMetadata", "Test Q - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psMetadata_05.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_05.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_05.c	(revision 3057)
@@ -0,0 +1,327 @@
+
+
+/** @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.16 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2005-01-13 23:34:56 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = NULL;
+    psMetadataItem *item7 = NULL;
+    //    psMetadataItem *item8 = NULL;
+    psMetadata *metadata = NULL;
+    FILE *fd = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_TYPE_F32, PS_META_PRIMITIVE, "I am a float", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_TYPE_F64, PS_META_PRIMITIVE,"I am a double", 6.28);
+    item7 = psMetadataItemAlloc("myItem7", PS_TYPE_PTR, PS_META_STR, "I am a string", "GNIRTS");
+    //    item8 = psMetadataItemAlloc("myItem8", PS_TYPE_PTR, 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");
+        if (!psMetadataSetIterator(metadata, 2)) {
+            psError(PS_ERR_UNKNOWN,true,"Failed to set iterator");
+            return 100;
+        }
+        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(PS_ERR_UNKNOWN, true,"psMetadataGetPrevious did not return an item from metadata.");
+            return 45;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if ( psMetadataGetPrevious(metadata,NULL,1) != NULL) {
+            psError(PS_ERR_UNKNOWN, true,"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");
+    }
+
+    if (psMetadataItemPrint(fd, "S32 = %ld\n", item2) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 10;
+    }
+
+    if (psMetadataItemPrint(fd, "BOL = %ld\n", item3) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 11;
+    }
+
+    if (psMetadataItemPrint(fd, "F32 = %g\n", item5) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 12;
+    }
+
+    if (psMetadataItemPrint(fd, "F64 = %g\n", item6) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 13;
+    }
+
+    if (psMetadataItemPrint(fd, "STR = %s\n", item7) == false) {
+        printf("ERROR: Return type should be true\n");
+        return 14;
+    }
+    //    psLogMsg(__func__,PS_LOG_INFO,"Attempt to print item of invalid type, should generate error message");
+    //    if (psMetadataItemPrint(fd, "UNK = \n", item8) == true) {
+    //        printf("ERROR: Return type should be false\n");
+    //        fclose(fd);
+    //        return 15;
+    //    }
+    fclose(fd);
+
+    fd = fopen("./tst_psMetadata05_OUT", "r");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for reading\n");
+    }
+
+    char line[256];
+    char truth1[] = "S32 = 55";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth1, 8)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth1);
+    }
+
+    char truth2[] = "BOL = 0";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth2, 7)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth2);
+    }
+
+    char truth3[] = "F32 = 3.14";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth3, 10)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth3);
+    }
+
+    char truth4[] = "F64 = 6.28";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth4, 10)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth4);
+    }
+
+    char truth5[] = "STR = GNIRTS";
+    fgets(line, 256, fd);
+    if(strncmp(line, truth5, 12)) {
+        printf("ERROR: Data in file is not as expected. Value: %s. Should be: %s\n", line, truth5);
+    }
+
+    fclose(fd);
+    printFooter(stdout, "psMetadata", "Test F - Write metadata item to file", true);
+    /*
+        // 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);
+        if( psMetadataSetIterator(NULL, 0)) {
+            psError(PS_ERR_UNKNOWN,true,"Set iterator did not detect invalid parameter.");
+            return 101;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if( psMetadataSetIterator(metadata,0)) {
+            psError(PS_ERR_UNKNOWN,true,"Set iterator did not detect null list.");
+            return 102;
+        }
+        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(PS_ERR_UNKNOWN, true,"psMetadataGetNext did not return null for null metadata.");
+            return 40;
+        }
+        tmpList = metadata->list;
+        metadata->list = NULL;
+        if ( psMetadataGetNext(metadata, "myItem2", 0) != NULL ) {
+            psError(PS_ERR_UNKNOWN, true,"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, false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 50;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/collections/tst_psMetadata_06.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_06.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_06.c	(revision 3057)
@@ -0,0 +1,147 @@
+
+/** @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.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:19:07 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem)
+{
+    printf("Key Name: %8s  ", metadataItem->name);
+    printf("Key pType: %2d  ", metadataItem->pType);
+    printf("Key mdType: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type) {
+    case PS_META_LIST:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_PRIMITIVE:
+        switch(metadataItem->pType) {
+        case PS_TYPE_BOOL:
+            printf("Key Value: %15d  ", metadataItem->data.B);
+            break;
+        case PS_TYPE_S32:
+            printf("Key Value: %15d  ", metadataItem->data.S32);
+            break;
+        case PS_TYPE_F32:
+            printf("Key Value: %15.3f  ", metadataItem->data.F32);
+            break;
+        case PS_TYPE_F64:
+            printf("Key Value: %15.3f  ", metadataItem->data.F64);
+            break;
+        default:
+            printf("Bad type: %d ", metadataItem->pType);
+        }
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+}
+
+
+psS32 main( psS32 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_TYPE_BOOL, PS_META_PRIMITIVE, "I am a boolean", true);
+    item1b = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 111);
+    item1c = psMetadataItemAlloc("myItem1", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 222);
+    item2a = psMetadataItemAlloc("myItem2", PS_TYPE_S32, PS_META_PRIMITIVE, "I am a signed integer", 333);
+    item2b = psMetadataItemAlloc("myItem2", PS_TYPE_PTR, PS_META_LIST, "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(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node top.");
+        return 20;
+    }
+    if (!psMetadataAddItem(metadata, item1b, PS_LIST_HEAD)) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psMetadataAddItem returned false for adding a node to existing leaf node.");
+        return 23;
+    }
+    if (!psMetadataAddItem(metadata, item2b, PS_LIST_HEAD)) {
+        psError(PS_ERR_UNKNOWN, true,"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, false) != 0 ) {
+        psError(PS_ERR_UNKNOWN, true,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    psS32 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/rel4/psLib/test/collections/tst_psMetadata_07.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psMetadata_07.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psMetadata_07.c	(revision 3057)
@@ -0,0 +1,46 @@
+/** @file  tst_psMetadata_07.c
+*
+*  @brief Test driver for psMetadataIO functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read an XML config file
+*     Test B - Free data
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-03 23:38:41 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+#include "pslib.h"
+#include "psTest.h"
+
+
+int main(int argc, char* argv[])
+{
+    // Test A - Read an XML config file
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read an XML config file");
+    int res = 0;
+    psU32 nFail = 0;
+    psMetadata *md = NULL;
+    md = psMetadataParseConfigXml(md, &nFail, "../../config/psTime.xml", true);
+    if (nFail != 0) {
+        printf("psMetadataParseConfigXml returned error %d\n", res);
+    }
+    psFree(md);
+    printFooter(stdout, "psMetadata", "Test A - Read an XML config file", true);
+
+
+    // Test B - Free data
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Free data");
+    psMemCheckLeaks(0, NULL, stdout, false);
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test B - Free data", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/tst_psScalar.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psScalar.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psScalar.c	(revision 3057)
@@ -0,0 +1,138 @@
+/** @file  tst_psScalar.c
+ *
+ *  @brief Contains the tests for psScalar.[ch]
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.2 $
+ *           $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-08 19:18:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 testScalarAlloc(void);
+static psS32 testScalarCopy(void);
+
+#define tstScalarAllocByType(datatype,value)                                                                    \
+scalar = psScalarAlloc(value,PS_TYPE_##datatype);                                                               \
+if(scalar == NULL) {                                                                                            \
+    psError(PS_ERR_UNKNOWN,true,"psScalarAlloc returned NULL.");                                                \
+    return 1+value;                                                                                             \
+} else {                                                                                                        \
+    if( (scalar->type.type != PS_TYPE_##datatype) && (scalar->data.datatype != value) ) {                       \
+        psError(PS_ERR_UNKNOWN,true,"psScalarAlloc created object with unexpected type and/or value");          \
+        return 2+value;                                                                                         \
+    }                                                                                                           \
+}                                                                                                               \
+psFree(scalar);
+
+#define tstScalarCopyByType(datatype,value)                                                                               \
+scalarOrig = psScalarAlloc(value,PS_TYPE_##datatype);                                                                     \
+scalarCopy = psScalarCopy(scalarOrig);                                                                                    \
+if(scalarCopy == NULL) {                                                                                                  \
+    psError(PS_ERR_UNKNOWN,true,"psScalarCopy returned NULL.");                                                           \
+    return 3+value;                                                                                                       \
+} else {                                                                                                                  \
+    if( (scalarCopy->type.type != scalarOrig->type.type) || (scalarCopy->data.datatype != scalarOrig->data.datatype) ) {  \
+        psError(PS_ERR_UNKNOWN,true,"psScalarCopy did not copy the original scalar by type and/or value");                \
+        return 4+value;                                                                                                   \
+    }                                                                                                                     \
+}                                                                                                                         \
+psFree(scalarCopy);                                                                                                       \
+psFree(scalarOrig);
+
+testDescription tests[] = {
+                              {testScalarAlloc,783,"psScalarAlloc",0,false},
+                              {testScalarCopy,784,"psScalarCopy",0,false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if ( ! runTestSuite(stderr,"psScalar",tests,argc,argv) ) {
+        psError(PS_ERR_UNKNOWN,true,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+psS32 testScalarAlloc(void)
+{
+    psScalar* scalar;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psScalarAlloc shall create scalar data objects");
+
+    // Verify the proper allocation/deallocation of scalar objects of valid types
+    tstScalarAllocByType(S8,10);
+    tstScalarAllocByType(U8,12);
+    tstScalarAllocByType(S16,14);
+    tstScalarAllocByType(U16,16);
+    tstScalarAllocByType(S32,18);
+    tstScalarAllocByType(U32,20);
+    tstScalarAllocByType(S64,22);
+    tstScalarAllocByType(U64,24);
+    tstScalarAllocByType(F32,26);
+    tstScalarAllocByType(F64,28);
+    tstScalarAllocByType(C32,30);
+    tstScalarAllocByType(C64,32);
+
+    // Verify return is null for invalid scalar type
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    scalar = psScalarAlloc(true,PS_TYPE_BOOL);
+    if(scalar != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psScalarAlloc did not return null for invalid type");
+        return 5;
+    }
+
+    return 0;
+}
+
+psS32 testScalarCopy(void)
+{
+    psScalar*  scalarOrig;
+    psScalar*  scalarCopy;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psScalarCopy shall copy scalar objects");
+
+    // Verify the proper copying of scalar objects for all valid types
+    tstScalarCopyByType(S8,100);
+    tstScalarCopyByType(U8,110);
+    tstScalarCopyByType(S16,120);
+    tstScalarCopyByType(U16,130);
+    tstScalarCopyByType(S32,140);
+    tstScalarCopyByType(U32,150);
+    tstScalarCopyByType(S64,160);
+    tstScalarCopyByType(U64,170);
+    tstScalarCopyByType(F32,180);
+    tstScalarCopyByType(F64,190);
+    tstScalarCopyByType(C32,200);
+    tstScalarCopyByType(C64,210);
+
+    // Verify the return is null for invalid scalar type in the original
+    scalarOrig = psScalarAlloc(0,PS_TYPE_S8);
+    scalarOrig->type.type = PS_TYPE_BOOL;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    scalarCopy = psScalarCopy(scalarOrig);
+    if(scalarCopy != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psScalarCopy did not return NULL for invalid type");
+        return 6;
+    }
+    psFree(scalarOrig);
+
+    // Verify the return is null for null original scalar value
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    scalarCopy = psScalarCopy(NULL);
+    if(scalarCopy != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psScalarCopy did not return NULL for NULL argument");
+        return 7;
+    }
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/collections/tst_psVector.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psVector.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psVector.c	(revision 3057)
@@ -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.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:07:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+psS32 main(psS32 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(psS32 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(psS32 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(psS32 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);
+    psS32 leaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if(leaks != 0) {
+        printf("ERROR: Found %d memory leaks\n",leaks);
+    }
+    psS32 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/rel4/psLib/test/collections/tst_psVectorSort_01.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psVectorSort_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psVectorSort_01.c	(revision 3057)
@@ -0,0 +1,183 @@
+/** @file  tst_psVectorSort_01.c
+ *
+ *  @brief Test driver for psVectorSort functions
+ *
+ *  This test driver contains the following tests for psVectorSort test point 1:
+ *     A)  Sort input vector to output vector for all types
+ *     B)  Sort input float vector into itself
+ *     C)  Attempt to sort vector with invalid type (i.e. PS_TYPE_BOOL)
+ *     D)  Sort input vector with zero items 
+ *     C)  Free float vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-09 00:47:20 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define tstVectorSortByType(datatype,value)   \
+in = psVectorAlloc(7,PS_TYPE_##datatype); \
+in->n = 7;  \
+out = psVectorAlloc(7,PS_TYPE_##datatype); \
+out->n = 7;  \
+in->data.datatype[0] = 7+value; \
+in->data.datatype[1] = 9+value; \
+in->data.datatype[2] = 3+value; \
+in->data.datatype[3] = 1+value; \
+in->data.datatype[4] = 5+value; \
+in->data.datatype[5] = 5+value; \
+in->data.datatype[6] = 0+value; \
+tempVec = out; \
+out = psVectorSort(out, in); \
+if(tempVec != out) {  \
+    psError(PS_ERR_UNKNOWN,true,"Return value not equal to orignal output argument passed to function"); \
+    return 5; \
+} \
+if(out->data.datatype[0] != in->data.datatype[6]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[0] type %s",#datatype); \
+    return 10; \
+} \
+if(out->data.datatype[1] != in->data.datatype[3]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[1] type %s",#datatype); \
+    return 20; \
+} \
+if(out->data.datatype[2] != in->data.datatype[2]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[2] type %s",#datatype); \
+    return 30; \
+} \
+if(out->data.datatype[3] != in->data.datatype[4]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[3] type %s",#datatype); \
+    return 40; \
+} \
+if(out->data.datatype[4] != in->data.datatype[5]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[4] %s",#datatype); \
+    return 50; \
+} \
+if(out->data.datatype[5] != in->data.datatype[0]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[5] %s",#datatype); \
+    return 60; \
+} \
+if(out->data.datatype[6] != in->data.datatype[1]) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper sort out[6] %s",#datatype); \
+    return 70; \
+} \
+psFree(in); \
+psFree(out);
+
+
+
+psS32 main(psS32 argc,
+           char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+    psVector *tempVec = NULL;
+
+    // Test A - Verify the sort for all supported types
+    printPositiveTestHeader(stdout,"psVectorSort","Sort all types");
+    tstVectorSortByType(S8,0);
+    tstVectorSortByType(S16,1);
+    tstVectorSortByType(S32,2);
+    tstVectorSortByType(S64,3);
+    tstVectorSortByType(U8,4);
+    tstVectorSortByType(U16,5);
+    tstVectorSortByType(U32,6);
+    tstVectorSortByType(U64,7);
+    tstVectorSortByType(F32,8);
+    tstVectorSortByType(F64,9);
+    printFooter(stdout,"psVectorSort","Sort all types",true);
+
+    // Test B - Sort input vector into itself
+    printPositiveTestHeader(stdout,"psVectorSort", "Sort input float vector into itself");
+    in = psVectorAlloc(7, PS_TYPE_F32);
+    in->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;
+    in = psVectorSort(in, in);
+    if(in->data.F32[0] != -20.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[0]");
+        return 100;
+    }
+    if(in->data.F32[1] != 1.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[1]");
+        return 200;
+    }
+    if(in->data.F32[2] != 3.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[2]");
+        return 300;
+    }
+    if(in->data.F32[3] != 5.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[3]");
+        return 400;
+    }
+    if(in->data.F32[4] != 5.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[4]");
+        return 500;
+    }
+    if(in->data.F32[5] != 7.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[5]");
+        return 600;
+    }
+    if(in->data.F32[6] != 9.0f) {
+        psError(PS_ERR_UNKNOWN,true,"Improper self sort in[6]");
+        return 700;
+    }
+    printFooter(stdout, "psVectorSort", "Sort input float vector into itself", true);
+
+    // Test C - Attempt to sort vector with invalid type
+    printPositiveTestHeader(stdout,"psVectorSort","Invalid vector type");
+    in->type.type = PS_TYPE_BOOL;
+    out = psVectorAlloc(7,PS_TYPE_F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error messgae");
+    tempVec = psVectorSort(out,in);
+    if(tempVec != out) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the specified output vector");
+        return 33;
+    }
+    psFree(out);
+    printFooter(stdout,"psVectorSort","Invalid vector type",true);
+
+    // Test D - Sort vector with zero elements
+    printPositiveTestHeader(stdout,"psVectorSort","Sort zero element vector");
+    out = psVectorAlloc(7,PS_TYPE_F32);
+    tempVec = out;
+    in->n = 0;
+    out = psVectorSort(out,in);
+    if(tempVec != out) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the specified output vector");
+        return 44;
+    }
+    if(out->n != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not proper set the number of elements to zero");
+        return 55;
+    }
+    printFooter(stdout,"psVectorSort","Sort zero element vector",true);
+
+
+    // Test D - Free float vectors
+    printPositiveTestHeader(stdout,"psVectorSort", "Free float vectors");
+    psFree(in);
+    psFree(out);
+    if ( psMemCheckLeaks(0, NULL, stdout, false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psS32 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/rel4/psLib/test/collections/tst_psVectorSort_02.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psVectorSort_02.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psVectorSort_02.c	(revision 3057)
@@ -0,0 +1,180 @@
+/** @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)  Attempt to sort with null input vector
+ *     D)  Sort with output vector which needs to be resized
+ *     E)  Sort input vector with zero elements
+ *     F)  Attempt to sort input vector with invalid type
+ *     G)  Free vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-09 21:33:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define tstVectorSortIndexByType(datatype,value) \
+in = psVectorAlloc( 5, PS_TYPE_##datatype ); \
+in->n = 5; \
+in->data.datatype[0] = 7+value; \
+in->data.datatype[1] = 9+value; \
+in->data.datatype[2] = 5+value; \
+in->data.datatype[3] = 1+value; \
+in->data.datatype[4] = 5+value; \
+out = psVectorSortIndex(out,in); \
+if(out->type.type != PS_TYPE_U32) { \
+    psError(PS_ERR_UNKNOWN,true,"Output vector is not of type PS_TYPE_U32"); \
+    return 10; \
+} \
+if(out->data.U32[0] != 3 ) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[0] = %ld",out->data.U32[0]); \
+    return 20; \
+} \
+if(out->data.U32[1] != 2 ) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[1] = %ld",out->data.U32[1]); \
+    return 30; \
+} \
+if(out->data.U32[2] != 4 ) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[2] = %ld",out->data.U32[2]); \
+    return 40; \
+} \
+if(out->data.U32[3] != 0 ) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[3] = %ld",out->data.U32[3]); \
+    return 50; \
+} \
+if(out->data.U32[4] != 1 ) { \
+    psError(PS_ERR_UNKNOWN,true,"Improper index sort out[4] = %ld",out->data.U32[4]); \
+    return 60; \
+} \
+psFree(in);
+
+psS32 main(psS32 argc,
+           char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+    psVector *tempVect = NULL;
+
+    // Test A - Sort vectors by index for all types
+    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort by index for all types");
+    tstVectorSortIndexByType(S8,0)
+    tstVectorSortIndexByType(U8,1)
+    tstVectorSortIndexByType(S16,2)
+    tstVectorSortIndexByType(U16,3)
+    tstVectorSortIndexByType(S32,4)
+    tstVectorSortIndexByType(U32,5)
+    tstVectorSortIndexByType(S64,6)
+    tstVectorSortIndexByType(U64,7)
+    tstVectorSortIndexByType(F32,8)
+    tstVectorSortIndexByType(F64,9)
+    psFree(out);
+    printFooter(stdout,"psVectorSortIndex","Sort by index for all types",true);
+
+    // Test  C  Attempt to sort with null input vector
+    printPositiveTestHeader(stdout,"psVectorSortIndex","Attempt to sort with NULL input");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    in = NULL;
+    out = psVectorAlloc(5,PS_TYPE_U32);
+    out = psVectorSortIndex(out,in);
+    if(out != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with NULL input specified");
+        return 111;
+    }
+    printFooter(stdout,"psVectorSortIndex","Attempt to sort with NULL input",true);
+
+    // Test  D  Sort with output vector which needs to be resized
+    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort with resize output vector");
+    in = psVectorAlloc(5,PS_TYPE_U8);
+    for(psS32 m=0; m<5; m++) {
+        in->data.U8[m]= 20-m;
+    }
+    out = psVectorAlloc(3,PS_TYPE_U32);
+    out = psVectorSortIndex(out,in);
+    if(out->n != 5) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly resize output vector");
+        return 112;
+    }
+    if(out->data.U32[0] != 4) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[0] = %d",out->data.U32[0]);
+        return 113;
+    }
+    if(out->data.U32[1] != 3) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[1] = %d",out->data.U32[1]);
+        return 114;
+    }
+    if(out->data.U32[2] != 2) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[2] = %d",out->data.U32[2]);
+        return 115;
+    }
+    if(out->data.U32[3] != 1) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[3] = %d",out->data.U32[3]);
+        return 116;
+    }
+    if(out->data.U32[4] != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not properly sort index out[4] = %d",out->data.U32[4]);
+        return 117;
+    }
+    psFree(in);
+    psFree(out);
+    printFooter(stdout,"psVectorSortIndex","Sort with resize output vector",true);
+
+    // Test E - Sort input vector with zero elements
+    printPositiveTestHeader(stdout,"psVectorSortIndex","Sort with input vector with zero elements");
+    in = psVectorAlloc(5,PS_TYPE_U8);
+    out = psVectorAlloc(5,PS_TYPE_U32);
+    in->n = 0;
+    out->n = 0;
+    tempVect = out;
+    out = psVectorSortIndex(out,in);
+    if ( out != tempVect ) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the same output vector");
+        return 118;
+    }
+    in->n=5;
+    out->n=5;
+    psFree(out);
+    psFree(in);
+    printFooter(stdout,"psVectorSortIndex","Sort with input vector with zero elements",true);
+
+    // Test F - Attempt to sort input vector with invalid type
+    printPositiveTestHeader(stdout,"psVectorSortIndex","Attempt to sort with invalid type");
+    in = psVectorAlloc(5,PS_TYPE_U8);
+    out = psVectorAlloc(5,PS_TYPE_U32);
+    tempVect = out;
+    in->type.type = PS_TYPE_BOOL;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate two error messages(psVectorSort,psVectorSortIndex)");
+    out = psVectorSortIndex(out,in);
+    if( out != tempVect) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the same output vector");
+        return 119;
+    }
+    in->type.type = PS_TYPE_U8;
+    psFree(in);
+    psFree(out);
+    printFooter(stdout,"psVectorSortIndex","Attempt to sort with invalid type",true);
+
+    // Test G - Free vectors
+    printPositiveTestHeader(stdout,"psVectorSortIndex", "Free vectors");
+    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+        return 222;
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 333;
+    }
+    printFooter(stdout, "psVectorSort", "Free vectors", true);
+
+}
Index: /branches/rel4/psLib/test/collections/tst_psVectorSort_03.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psVectorSort_03.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psVectorSort_03.c	(revision 3057)
@@ -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.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:07:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+psS32 main(psS32 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(psS32 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(psS32 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);
+    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free float vectors", true);
+
+}
Index: /branches/rel4/psLib/test/collections/tst_psVectorSort_04.c
===================================================================
--- /branches/rel4/psLib/test/collections/tst_psVectorSort_04.c	(revision 3057)
+++ /branches/rel4/psLib/test/collections/tst_psVectorSort_04.c	(revision 3057)
@@ -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.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:22:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+psS32 main(psS32 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);
+    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory blocks\n", nLeaks);
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free arays", true);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/collections/verified/tst_psArray.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psArray.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psArray.stderr	(revision 3057)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psArrayRealloc (psArray.c:<LINENO>)
+    psArrayRealloc must be given a non-NULL psArray to resize.
+<DATE><TIME>|<HOST>|E|psArrayRemove (psArray.c:<LINENO>)
+    Specified psArray can not be NULL.
Index: /branches/rel4/psLib/test/collections/verified/tst_psArray.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psArray.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psArray.stdout	(revision 3057)
@@ -0,0 +1,120 @@
+/***************************** 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{Reallocate with a null array}                      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Error message generator                                    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Reallocate with a null array} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Remove valid item}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Array size after removal = 2
+ts[0].x = 10 ts[0].y = 10.10
+ts[1].x = 20 ts[1].y = 20.20
+
+---> TESTPOINT PASSED (psArray{Remove valid item} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Remove invalid item from array}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Remove invalid item from array} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Remove item from null array}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Remove item from null array} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Remove null item from array}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Remove null item from array} | 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/rel4/psLib/test/collections/verified/tst_psArray01.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psArray01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psArray01.stdout	(revision 3057)
@@ -0,0 +1,67 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray01.c                                            *
+*            TestPoint: psArray{Create void pointer array}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Create void pointer array} | tst_psArray01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray01.c                                            *
+*            TestPoint: psArray{Add data to void pointer array}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 100 ts[0].y = 101.00
+ts[1].x = 90 ts[1].y = 90.90
+ts[2].x = 80 ts[2].y = 80.80
+ts[3].x = 70 ts[3].y = 70.70
+ts[4].x = 60 ts[4].y = 60.60
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 40 ts[6].y = 40.40
+ts[7].x = 30 ts[7].y = 30.30
+ts[8].x = 20 ts[8].y = 20.20
+ts[9].x = 10 ts[9].y = 10.10
+array size = 10
+array population = 10
+
+---> TESTPOINT PASSED (psArray{Add data to void pointer array} | tst_psArray01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray01.c                                            *
+*            TestPoint: psArray{Sort data in array}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 10 ts[0].y = 10.10
+ts[1].x = 20 ts[1].y = 20.20
+ts[2].x = 30 ts[2].y = 30.30
+ts[3].x = 40 ts[3].y = 40.40
+ts[4].x = 50 ts[4].y = 50.50
+ts[5].x = 60 ts[5].y = 60.60
+ts[6].x = 70 ts[6].y = 70.70
+ts[7].x = 80 ts[7].y = 80.80
+ts[8].x = 90 ts[8].y = 90.90
+ts[9].x = 100 ts[9].y = 101.00
+
+---> TESTPOINT PASSED (psArray{Sort data in array} | tst_psArray01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray01.c                                            *
+*            TestPoint: psArray{Attempt to sort array}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Attempt to sort array} | tst_psArray01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray01.c                                            *
+*            TestPoint: psArray{Free void pointer array}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Free void pointer array} | tst_psArray01.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psBitSet.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psBitSet.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psBitSet.stderr	(revision 3057)
@@ -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|psBitSetAlloc (psBitSet.c:<LINENO>)
+    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|psBitSetSet (psBitSet.c:<LINENO>)
+    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|psBitSetSet (psBitSet.c:<LINENO>)
+    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|psBitSetSet (psBitSet.c:<LINENO>)
+    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|psBitSetTest (psBitSet.c:<LINENO>)
+    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|psBitSetTest (psBitSet.c:<LINENO>)
+    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|psBitSetTest (psBitSet.c:<LINENO>)
+    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|psBitSetOp (psBitSet.c:<LINENO>)
+    The psBitSet operand must be the same size.
+<DATE><TIME>|<HOST>|I|testBitSet06
+    Following is an error.
+<DATE><TIME>|<HOST>|E|psBitSetOp (psBitSet.c:<LINENO>)
+    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|psBitSetOp (psBitSet.c:<LINENO>)
+    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/rel4/psLib/test/collections/verified/tst_psHash00.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash00.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash00.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psHash01.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash01.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash01.stderr	(revision 3057)
@@ -0,0 +1,12 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashAdd with null table
+<DATE><TIME>|<HOST>|E|psHashAdd (psHash.c:<LINENO>)
+    Input psHash can not be NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashAdd with null key
+<DATE><TIME>|<HOST>|E|psHashAdd (psHash.c:<LINENO>)
+    Input key can not be NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashAdd with null data
+<DATE><TIME>|<HOST>|E|psHashAdd (psHash.c:<LINENO>)
+    Input data can not be NULL.
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash01.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash01.stdout	(revision 3057)
@@ -0,0 +1,69 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashAlloc}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashAlloc} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashAdd}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashAdd} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash replace item{psHashAdd}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash replace item{psHashAdd} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHashAdd{NULL hash table}                                 *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Hash table can not be NULL.                                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashAdd{NULL hash table} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHashAdd{NULL key}                                        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Hash key can not be NULL.                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashAdd{NULL hash key} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHashAdd{NULL hash data}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Hash data can not be NULL.                                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashAdd{NULL hash data} | tst_psHash01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashFree}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashFree()} | tst_psHash01.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash02.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash02.stderr	(revision 3057)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashLookup with null table
+<DATE><TIME>|<HOST>|E|psHashLookup (psHash.c:<LINENO>)
+    Input psHash can not be NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashLookup with null key
+<DATE><TIME>|<HOST>|E|psHashLookup (psHash.c:<LINENO>)
+    Input key can not be NULL.
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash02.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash02.stdout	(revision 3057)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash02.c                                             *
+*            TestPoint: psHash functions{psHashLookup}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashLookup} | tst_psHash02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash02.c                                             *
+*            TestPoint: psHashLookup{Invalid key}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Key is not found in the table                              *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashLookup{Invalid key} | tst_psHash02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash02.c                                             *
+*            TestPoint: psHashLookup{NULL table}                                   *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Can not lookup with NULL table                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashLookup{NULL table} | tst_psHash02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash02.c                                             *
+*            TestPoint: psHashLookup{NULL key}                                     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Can not lookup with NULL key.                              *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashLookup{NULL key} | tst_psHash02.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash03.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash03.stderr	(revision 3057)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashRemove with null table
+<DATE><TIME>|<HOST>|E|psHashRemove (psHash.c:<LINENO>)
+    Input psHash can not be NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message: psHashRemove with null key
+<DATE><TIME>|<HOST>|E|psHashRemove (psHash.c:<LINENO>)
+    Input key can not be NULL.
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash03.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash03.stdout	(revision 3057)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHash functions{psHashRemove}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashRemove()} | tst_psHash03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHashRemove{Invalid key}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Key is not found in table                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashRemove{Invalid key} | tst_psHash03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHashRemove{NULL table}                                   *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Can not remove with NULL table                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashRemove{NULL table} | tst_psHash03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHashRemove{NULL key}                                     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Can not remove with NULL key                               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashRemove{NULL key} | tst_psHash03.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash04.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash04.stdout	(revision 3057)
@@ -0,0 +1,24 @@
+/***************************** 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)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash04.c                                             *
+*            TestPoint: psHashKeyList{NULL table}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Can not lookup with NULL table                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHashKeyList{NULL table} | tst_psHash04.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psHash05.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psHash05.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psHash05.stderr	(revision 3057)
@@ -0,0 +1,13 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash05.c                                             *
+*            TestPoint: psHash{psHashToArray}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|hashToArray
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psHashToArray (psHash.c:<LINENO>)
+    Input psHash can not be NULL.
+
+---> TESTPOINT PASSED (psHash{psHashToArray} | tst_psHash05.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psList.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psList.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psList.stderr	(revision 3057)
@@ -0,0 +1,116 @@
+/***************************** 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>|E|psListAdd (psList.c:<LINENO>)
+    Specified psList reference is NULL.
+<DATE><TIME>|<HOST>|E|psListAdd (psList.c:<LINENO>)
+    Specified data item is NULL.
+<DATE><TIME>|<HOST>|I|testListAdd
+    Following should error with invalid insert location
+<DATE><TIME>|<HOST>|E|psListIteratorSet (psList.c:<LINENO>)
+    Specified location, -10, is invalid.
+<DATE><TIME>|<HOST>|I|testListAdd
+    Following should be a warning.
+<DATE><TIME>|<HOST>|W|psListAdd
+    Specified location, 9, is beyond the end of the list.  Adding data item to 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|psListGet (psList.c:<LINENO>)
+    Specified psList reference is NULL.
+<DATE><TIME>|<HOST>|E|psListIteratorSet (psList.c:<LINENO>)
+    Specified location, 5, is invalid.
+<DATE><TIME>|<HOST>|E|psListGet (psList.c:<LINENO>)
+    Specified location, 5, is invalid.
+<DATE><TIME>|<HOST>|E|psListIteratorSet (psList.c:<LINENO>)
+    Specified location, 4, is invalid.
+<DATE><TIME>|<HOST>|E|psListGet (psList.c:<LINENO>)
+    Specified location, 4, is invalid.
+
+---> 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 (psList.c:<LINENO>)
+    Specified psList reference is NULL.
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemoveData (psList.c:<LINENO>)
+    Specified data item is NULL.
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemoveData (psList.c:<LINENO>)
+    Specified data item is not found in the 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'
+
+---> 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/rel4/psLib/test/collections/verified/tst_psScalar.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psScalar.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psScalar.stderr	(revision 3057)
@@ -0,0 +1,34 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psScalar.c                                             *
+*            TestPoint: psScalar{psScalarAlloc}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testScalarAlloc
+    psScalarAlloc shall create scalar data objects
+<DATE><TIME>|<HOST>|I|testScalarAlloc
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psScalarAlloc (psScalar.c:<LINENO>)
+    Specified datatype (4865) is unsupported by psScalar.
+
+---> TESTPOINT PASSED (psScalar{psScalarAlloc} | tst_psScalar.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psScalar.c                                             *
+*            TestPoint: psScalar{psScalarCopy}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testScalarCopy
+    psScalarCopy shall copy scalar objects
+<DATE><TIME>|<HOST>|I|testScalarCopy
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psScalarCopy (psScalar.c:<LINENO>)
+    Specified datatype (4865) is unsupported by psScalar.
+<DATE><TIME>|<HOST>|I|testScalarCopy
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psScalarCopy (psScalar.c:<LINENO>)
+    Can not copy a NULL psScalar.
+
+---> TESTPOINT PASSED (psScalar{psScalarCopy} | tst_psScalar.c)
+
Index: /branches/rel4/psLib/test/collections/verified/tst_psSort_01.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psSort_02.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psSort_03.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psSort_03.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psSort_04.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 3057)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> |<HOST>|E|         psSort| : Line 119 - Null input vector
Index: /branches/rel4/psLib/test/collections/verified/tst_psSort_04.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVector.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector.stderr	(revision 3057)
@@ -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|psVectorRealloc (psVector.c:<LINENO>)
+    psVectorRealloc must a given a non-NULL psVector to resize.  Desired datatype unknown.
Index: /branches/rel4/psLib/test/collections/verified/tst_psVector.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error messgae
+<DATE><TIME>|<HOST>|E|psVectorSort (psVector.c:<LINENO>)
+    Input psVector is an unsupported type (4865).
Index: /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_01.stdout	(revision 3057)
@@ -0,0 +1,45 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Sort all types}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Sort all types} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Sort input float vector into itself}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Sort input float vector into itself} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Invalid vector type}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Invalid vector type} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Sort zero element vector}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Sort zero element vector} | 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/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stderr	(revision 3057)
@@ -0,0 +1,10 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psVectorSortIndex (psVector.c:<LINENO>)
+    psVectorSort can not sort a NULL psVector.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate two error messages(psVectorSort,psVectorSortIndex)
+<DATE><TIME>|<HOST>|E|psVectorSort (psVector.c:<LINENO>)
+    Input psVector is an unsupported type (4865).
+<DATE><TIME>|<HOST>|E|psVectorSortIndex (psVector.c:<LINENO>)
+    Input psVector is an unsupported type (4865).
Index: /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_02.stdout	(revision 3057)
@@ -0,0 +1,54 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Sort by index for all types}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Sort by index for all types} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Attempt to sort with NULL input}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Attempt to sort with NULL input} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Sort with resize output vector}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Sort with resize output vector} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Sort with input vector with zero elements} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Sort with input vector with zero elements} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Attempt to sort with invalid type}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Attempt to sort with invalid 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/rel4/psLib/test/collections/verified/tst_psVectorSort_03.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_03.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stderr	(revision 3057)
@@ -0,0 +1,2 @@
+<DATE><TIME>|<HOST>|E|psVectorSort (psVector.c:<LINENO>)
+    psVectorSort can not sort a NULL psVector.
Index: /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVectorSort_04.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVector_01.stderr
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVector_01.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVector_02.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 3057)
@@ -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/rel4/psLib/test/collections/verified/tst_psVector_03.stdout
===================================================================
--- /branches/rel4/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataIO/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/dataIO/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/.cvsignore	(revision 3057)
@@ -0,0 +1,5 @@
+temp
+tst_psLookupTable_01
+tst_psFits
+multi.fits
+table.fits
Index: /branches/rel4/psLib/test/dataIO/Makefile
===================================================================
--- /branches/rel4/psLib/test/dataIO/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/Makefile	(revision 3057)
@@ -0,0 +1,43 @@
+################################################################################
+##
+##  Makefile:   test/fileUtils
+##
+##  $Revision: 1.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-12 22:17:02 $
+##
+##  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_psLookupTable_01 \
+	tst_psFits
+
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/fileUtils'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
Index: /branches/rel4/psLib/test/dataIO/tst_psFits.c
===================================================================
--- /branches/rel4/psLib/test/dataIO/tst_psFits.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/tst_psFits.c	(revision 3057)
@@ -0,0 +1,1135 @@
+/** @file  tst_psFits.c
+*
+*  @brief Contains the tests for psFits.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-18 19:35:24 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (psU32 row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (psU32 col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static bool makeMulti(void);  // implicitly tests psFitsSetExtName
+static bool makeTable(void);
+const char* multiFilename = "multi.fits";
+const char* tableFilename = "table.fits";
+const int tableNumRows = 10;
+
+
+// N.B., the tests to Image read/write was liberally taken from the now
+// deprecated psImageReadSection/psImageWriteSection function tests.
+static psS32 testImageRead(void);
+static psS32 testImageWrite(void);
+
+static psS32 tst_psFitsAlloc( void );
+static psS32 tst_psFitsMoveExtName( void ); // also tests psFitsGetExtName
+static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum, psFitsGetSize
+static psS32 tst_psFitsReadHeader( void );
+static psS32 tst_psFitsReadHeaderSet( void );
+static psS32 tst_psFitsReadTable( void );
+
+testDescription tests[] = {
+                              {tst_psFitsAlloc, 801, "psFitsAlloc", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsMoveExtName", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsGetExtName", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsMoveExtNum", 0, false},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetExtNum", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetSize", 0, true},
+                              {tst_psFitsReadHeader, 804, "psFitsReadHeader", 0, false},
+                              {tst_psFitsReadHeaderSet,805, "psFitsReadHeaderSet", 0, false},
+                              {tst_psFitsReadTable,809, "psFitsReadTable", 0, false},
+                              {testImageRead,567, "psFitsReadImage", 0, false},
+                              {testImageWrite,569, "psFitsWriteImage", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+bool makeMulti(void)
+{
+
+    remove
+        (multiFilename);
+
+    psFits* fitsFile = psFitsAlloc(multiFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not create 'multi' FITS file.");
+        return false;
+    }
+
+    psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+    char extname[80];
+    for (int lcv = 0; lcv < 8; lcv++) {
+        snprintf(extname,80,"ext-%d", lcv);
+
+        psMetadata* header = psMetadataAlloc();
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                      PS_TYPE_S32, PS_META_PRIMITIVE,
+                      "psS32 Item", (psS32)lcv);
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                      PS_TYPE_F32, PS_META_PRIMITIVE,
+                      "psF32 Item", (float)(1.0f/(float)(1+lcv)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                      PS_TYPE_F64, PS_META_PRIMITIVE,
+                      "psF64 Item", (double)(1.0/(double)(1+lcv)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                      PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                      "psBool Item",
+                      (lcv%2 == 0));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYSTR",
+                      PS_TYPE_PTR, PS_META_STR,
+                      "String Item",
+                      extname);
+
+        // set the pixels in the image
+        psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
+        if (! psFitsWriteImage(fitsFile,header,image,1, extname) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not write image.");
+            return false;
+        }
+
+        psFree(header);
+    }
+    psFree(image);
+    psFree(fitsFile);
+
+    return true;
+}
+
+bool makeTable(void)
+{
+
+    remove
+        (tableFilename);
+
+    psFits* fitsFile = psFitsAlloc(tableFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not create 'table' FITS file.");
+        return false;
+    }
+
+    // make the PHU an image (per FITS standard, it must be)
+    psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+    if (! psFitsWriteImage(fitsFile,NULL,image,1,"primary") ) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not write PHU image.");
+        return false;
+    }
+
+    psFree(image);
+
+    // build a table structure
+    psArray* table = psArrayAlloc(tableNumRows);
+    table->n = 0;
+    for (int row = 0; row < tableNumRows; row++) {
+        psMetadata* header = psMetadataAlloc();
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                      PS_TYPE_S32, PS_META_PRIMITIVE,
+                      "psS32 Item", (psS32)row);
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                      PS_TYPE_F32, PS_META_PRIMITIVE,
+                      "psF32 Item", (float)(1.0f/(float)(1+row)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                      PS_TYPE_F64, PS_META_PRIMITIVE,
+                      "psF64 Item", (double)(1.0/(double)(1+row)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                      PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                      "psBool Item",
+                      (row%2 == 0));
+
+        psArrayAdd(table,0,header);
+    }
+
+    psFitsWriteTable(fitsFile, NULL, table, "table-1");
+
+    psFree(table);
+    psFree(fitsFile);
+
+    return true;
+}
+
+psS32 tst_psFitsAlloc( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fitsFile = psFitsAlloc(multiFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int extNum = psFitsGetExtNum(fitsFile);
+    if (extNum != 0) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc was not queued to the PHU, but to extension #%d.",
+                extNum);
+        return 2;
+    }
+
+    psFree(fitsFile);
+
+    // make sure the file doesn't already exist.
+    if (access("new.fits", F_OK) == 0) {
+        if (remove
+                ("new.fits") != 0) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Couldn't delete the new.fits file.");
+            return 3;
+        }
+    }
+
+    fitsFile = psFitsAlloc("new.fits");
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 4;
+    }
+
+    psFree(fitsFile);
+
+    // now, if psFitsAlloc actually created the file, I shouldn't error in removing it.
+    if (remove
+            ("new.fits") != 0) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc seemed to not have created a new file.");
+        return 5;
+    }
+
+
+    return 0;
+}
+
+psS32 tst_psFitsMoveExtName( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 2) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extName[80];
+    psRegion region = {0,0,0,0};
+
+    for (int lcv = 0; lcv < numHDUs; lcv++) {
+        snprintf(extName,80,"ext-%d",lcv);
+        // try to move to the named extension.
+        if (! psFitsMoveExtName(fits, extName) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to ext-%d.",
+                    lcv);
+            return 3;
+        }
+
+        // check to see if I can retrieve the name back from the psFits object.
+        char* nameFromFile = psFitsGetExtName(fits);
+        if (strcmp(nameFromFile,extName) != 0) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension name back ('%s' vs '%s'",
+                    nameFromFile, extName);
+            return 3;
+        }
+        psFree(nameFromFile);
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 4;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-1; lcv >= 0; lcv--) {
+        snprintf(extName,80,"ext-%d",lcv);
+        // try to move to the named extension.
+        if (! psFitsMoveExtName(fits, extName) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to ext-%d.",
+                    lcv);
+            return 5;
+        }
+
+        // check to see if I can retrieve the name back from the psFits object.
+        char* nameFromFile = psFitsGetExtName(fits);
+        if (strcmp(nameFromFile,extName) != 0) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension name back ('%s' vs '%s'",
+                    nameFromFile, extName);
+            return 5;
+        }
+        psFree(nameFromFile);
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 6;
+        }
+        psFree(image);
+    }
+
+    // check to see if given a bogus extension name, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(fits, "bogus") || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to non-existant HDU didn't fail.");
+        return 7;
+    }
+
+    // check to see if given a NULL psFits, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(NULL, "bogus") || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL psFits didn't fail.");
+        return 8;
+    }
+
+    // check to see if given a NULL extname, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(fits, NULL) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL extname didn't fail.");
+        return 9;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
+
+psS32 tst_psFitsMoveExtNum( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    // as a side test, let's make sure psFitsGetSize can handle NULL.
+    psLogMsg(__func__,PS_LOG_INFO,
+             "Following should be an error.");
+    psErrorClear();
+    if (psFitsGetSize(NULL) != 0 || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    if (numHDUs != 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    psRegion region = {0,0,0,0};
+
+    // test absolute positioning
+    for (int lcv = 0; lcv < numHDUs; lcv++) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, lcv, false) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 3;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 5;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 4;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-1; lcv >= 0; lcv--) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, lcv, false) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 5;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 6;
+        }
+        psFree(image);
+    }
+
+    // test relative positioning
+    psFitsMoveExtNum(fits,0,false);
+    for (int lcv = 1; lcv < numHDUs; lcv++) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, 1, true) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 13;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 13;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 14;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-2; lcv >= 0; lcv--) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, -1, true) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 15;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 15;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 16;
+        }
+        psFree(image);
+    }
+
+    // check to see if given a negative extension number, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, -1, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 21;
+    }
+
+    // check to see if relative positioning beyond PHU, it errors.
+    psFitsMoveExtNum(fits,0,false);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, -1, true) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 22;
+    }
+
+
+    // check to see if given a extension greater than the total #HDUs, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, numHDUs, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to a HDU beyond the file's contents didn't fail.");
+        return 31;
+    }
+
+    // check to see if relative positioning beyond PHU, it errors.
+    psFitsMoveExtNum(fits,numHDUs-1,false);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, 1, true) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 32;
+    }
+
+    // check to see if given a NULL psFits, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(NULL, 0, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL psFits didn't fail.");
+        return 40;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
+
+
+
+static psS32 tst_psFitsReadHeader( void )
+{
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extname[80];
+    for (int hdunum = 0; hdunum < numHDUs; hdunum++) {
+        snprintf(extname,80,"ext-%d",hdunum);
+
+        psFitsMoveExtNum(fits,hdunum,false);
+
+        psMetadata* header = psFitsReadHeader(NULL,fits);
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 3;
+        }
+
+        psMetadata* header2 = psMetadataAlloc();
+        header2 = psFitsReadHeader(header2,fits);
+        if (header2 == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 11;
+        }
+
+        if (header->list->size < 1 || header->list->size != header2->list->size) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Reading the header given a NULL input psMetadata differed "
+                    "from giving an existing psMetadata.");
+            return 12;
+        }
+
+        // check for the extra metadata items
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(header, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(header, "MYDBL",NULL);
+        psMetadataItem* boolItem = psMetadataLookup(header, "MYBOOL");
+        char* strItem = psMetadataLookupPtr(header, "MYSTR",NULL);
+
+        if (intItem != hdunum) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file.");
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+hdunum)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file.  Got %f vs %f",
+                    fltItem,1.0f/(float)(1+hdunum));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+hdunum)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file.  Got %g vs %g",
+                    dblItem, 1.0/(double)(1+hdunum));
+            return 22;
+        }
+
+        if (boolItem == NULL ||
+                boolItem->type != PS_META_PRIMITIVE ||
+                boolItem->pType != PS_TYPE_BOOL) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file.");
+            return 23;
+        }
+
+        if (strItem == NULL || strncmp(strItem,extname,strlen(extname)) != 0) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve string metadata item from file.  Got '%s' vs '%s' (%d)",
+                    strItem,extname,strlen(extname));
+            return 24;
+        }
+
+        psFree(header);
+        psFree(header2);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following should be an error (input psFits = NULL)");
+    psMetadata* header = psFitsReadHeader(NULL,NULL);
+
+    if (header != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadHeader didn't error on a NULL psFits.");
+        return 30;
+    }
+
+
+    psFree(fits);
+
+    return 0;
+}
+
+static psS32 tst_psFitsReadHeaderSet( void )
+{
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    // move to the middle
+    psFitsMoveExtNum(fits,numHDUs/2, false);
+
+    psHash* headerSet = psFitsReadHeaderSet(NULL, fits);
+
+    if (headerSet == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned NULL unexpectedly.");
+        return 3;
+    }
+
+    if (psFitsGetExtNum(fits) != numHDUs/2) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet changed the CHU.");
+        return 4;
+    }
+
+    char extname[80];
+    for (int i = 0; i < numHDUs; i++) {
+        if (i == 0) {
+            snprintf(extname, 80, "PHU");
+        } else {
+            snprintf(extname, 80, "ext-%d", i);
+        }
+
+        psMetadata* header = psHashLookup(headerSet, extname);
+
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader returned NULL unexpectedly for HDU#%d.",
+                    i);
+            return 5;
+        }
+
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+
+        if (intItem != i) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader for HDU#%d had a MYINT of %d, expected %d.",
+                    intItem, i);
+            return 6;
+        }
+
+    }
+
+    psHash* set2 = psHashAlloc(20);
+
+    if (psFitsReadHeaderSet(set2,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned non-NULL given a NULL psFits.");
+        return 10;
+    }
+
+    psHash* set3 = psHashAlloc(20);
+    psFitsReadHeaderSet(set3,fits);
+
+    if (set3 == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned NULL unexpectedly.");
+        return 11;
+    }
+
+    for (int i = 0; i < numHDUs; i++) {
+        if (i == 0) {
+            snprintf(extname, 80, "PHU");
+        } else {
+            snprintf(extname, 80, "ext-%d", i);
+        }
+
+        psMetadata* header = psHashLookup(set3, extname);
+
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader returned NULL unexpectedly for HDU#%d.",
+                    i);
+            return 5;
+        }
+
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+
+        if (intItem != i) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader for HDU#%d had a MYINT of %d, expected %d.",
+                    intItem, i);
+            return 6;
+        }
+
+    }
+
+
+
+    psFree(headerSet);
+    psFree(set3);
+    // set2 should have been freed by psFitsReadHeaderSet upon an error.
+
+    psFree(fits);
+
+    return 0;
+}
+
+static psS32 tst_psFitsReadTable( void )
+{
+
+
+    if (! makeTable() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(tableFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    psFitsMoveExtNum(fits,1,false);
+
+    psArray* table = psFitsReadTable(fits);
+
+    if (table == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadTable returned NULL unexpectedly.");
+        return 2;
+    }
+
+    if (table->n != tableNumRows) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Expected %d rows, but read %d.",
+                tableNumRows, table->n);
+        return 3;
+    }
+
+
+    for (int row = 0; row < table->n; row++) {
+        psMetadata* rowData = table->data[row];
+
+        psS32 intItem = psMetadataLookupS32(rowData, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(rowData, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(rowData, "MYDBL",NULL);
+        psBool boolItem = psMetadataLookupBool(rowData, "MYBOOL",NULL);
+
+        if (intItem != row) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file (row=%d).  Got %d vs %d",
+                    row, intItem, row);
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+row)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file (row=%d).  Got %f vs %f",
+                    row, fltItem,1.0f/(float)(1+row));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+row)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file (row=%d).  Got %g vs %g",
+                    row, dblItem, 1.0/(double)(1+row));
+            return 22;
+        }
+
+        if ( boolItem != ((row&0x01) == 0)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file (row=%d). Got %d vs %d",
+                    row, boolItem, ((row&0x01) == 0));
+            return 23;
+        }
+
+    }
+
+    psFree(table);
+    psFree(fits);
+
+    psArray* nullTest = psFitsReadTable(NULL);
+
+    if (nullTest != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadTable returned non-NULL when given NULL.");
+        return 30;
+    }
+
+    return 0;
+}
+
+psS32 testImageRead(void)
+{
+    psS32 N = 256;
+    psS32 M = 128;
+
+    /*
+        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; \
+        /*        psImagimge* 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); \
+        psFits* fits = psFitsAlloc(filename); \
+        psRegion region = {0,0,0,0}; \
+        if (! psFitsWriteImage(fits, NULL, img, 2, "primary")) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 1; \
+        } \
+        if (! psFitsUpdateImage(fits,img3, region, 1)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 2; \
+        } \
+        if (! psFitsWriteImage(fits,NULL, img3, 2, "extension")) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 3; \
+        } \
+        if (! psFitsUpdateImage(fits,img,region, 1)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 4; \
+        } \
+        psFree(img); \
+        psFree(fits); \
+        img = NULL; \
+        psFree(img3); \
+        img3 = NULL; \
+        fits = psFitsAlloc(filename); \
+        psRegion reg = {readM0, readM, readN0, readN}; \
+        img = psFitsReadImage(img, fits, reg, 0); \
+        img3 = psFitsReadImage(img3, fits, reg, 1); \
+        if (img3 == NULL) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 6; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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; \
+        psFitsMoveExtNum(fits,1, false); \
+        img3 = psFitsReadImage(img3, fits, reg, 0); \
+        img = psFitsReadImage(img, fits, reg, 1); \
+        if (img == NULL) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 9; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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); \
+        psFree(fits); \
+    }
+
+    #define testReadType(TYP,filename) \
+    testReadTypeSize(1,1,0,0,0,0,TYP,"tmpImages/1x1_" filename); \
+    testReadTypeSize(M,1,M/4,0,M*3/4,0,TYP,"tmpImages/Mx1_" filename); \
+    testReadTypeSize(1,N,0,N/4,0,N*3/4,TYP,"tmpImages/1xN_" filename); \
+    testReadTypeSize(M,N,M/4,N/4,M*3/4,N*3/4,TYP,"tmpImages/MxN_" filename);
+
+    mkdir("tmpImages",0777);
+
+    testReadTypeSize(1,1,0,0,0,0,U8,"tmpImages/1x1_" "U8.fits");
+    testReadTypeSize(M,1,M/4,0,M*3/4,0,U8,"tmpImages/Mx1_" "U8.fits");
+    testReadTypeSize(1,N,0,N/4,0,N*3/4,U8,"tmpImages/1xN_" "U8.fits");
+    testReadTypeSize(M,N,M/4,N/4,M*3/4,N*3/4,U8,"tmpImages/MxN_" "U8.fits");
+
+
+    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");
+
+    return 0;
+}
+
+psS32 testImageWrite(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psS32 m = 64;
+    psS32 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
+        ("tmpImages/writeTest.fits");
+    psRegion region = {
+                          0,0,0,0
+                      };
+    psFits* fits = psFitsAlloc("tmpImages/writeTest.fits");
+
+    if (! psFitsWriteImage(fits, NULL, img,1,NULL)) {
+        psError(PS_ERR_UNKNOWN, true,"Couldn't write writeTest.fits.");
+        return 14;
+    }
+    if (! psFitsUpdateImage(fits, img2, region, 0)) {
+        psError(PS_ERR_UNKNOWN, true,"Couldn't update writeTest.fits.");
+        return 15;
+    }
+    psFree(img);
+    psFree(img2);
+
+    // Did it really overwrite the pixel values?  Let's read it in and see.
+    psFree(fits);
+    fits = psFitsAlloc("tmpImages/writeTest.fits");
+    img = psFitsReadImage(NULL, fits, region, 0);
+    if (img == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"Could not read in writeTest.fits.");
+        return 16;
+    }
+    for (psU32 row=0;row<n;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(imgRow[col] - (row+2*col)) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"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 ( psFitsWriteImage(fits,NULL,NULL, 1, NULL) ) {
+        psError(PS_ERR_UNKNOWN, true,"psImageWriteSection did not return false when input image is NULL.");
+        return 20;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/dataIO/tst_psLookupTable_01.c
===================================================================
--- /branches/rel4/psLib/test/dataIO/tst_psLookupTable_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/tst_psLookupTable_01.c	(revision 3057)
@@ -0,0 +1,125 @@
+/** @file  tst_psLookupTable_01.c
+*
+*  @brief Test driver for psLookupTable functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read table and interpolate value
+*     Test B - Read table and interpolate all values
+*     Test C - Read beyond lower table bound
+*     Test D - Read beyond upper table bound
+*     Test E - Free data
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-23 19:38:38 $
+*
+*  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[])
+{
+
+
+    // Test A - Read table and interpolate value
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read table and interpolate value");
+    psLookupStatusType status1 = 0;
+    psF64 index1 = 2450905.0;
+    psF64 out1 = 0.0;
+    psLookupTable* table1 = NULL;
+
+    table1 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table1 = psLookupTableRead(table1);
+    out1 = psLookupTableInterpolate(table1, index1, 0, &status1);
+    if(fabs(out1-31.5)>FLT_EPSILON) {
+        printf("ERROR: Incorrect value, %lf. Expected 31.5\n", out1);
+    } else if(status1 != PS_LOOKUP_SUCCESS) {
+        printf("ERROR: Bad return status, %d\n", status1);
+    }
+    printFooter(stdout, "psMetadata", "Test A - Read table and interpolate value", true);
+
+
+    // Test B - Read table and interpolate all values
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read table and interpolate all values");
+    psU64 i = 0;
+    psF64 index2 = 2450905.0;
+    psVector *out2 = NULL;
+    psLookupTable* table2 = NULL;
+    psVector *stats2 = NULL;
+    psF64 truthData2[] = {31.5, 41317, 0};
+
+    table2 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table2 = psLookupTableRead(table2);
+    stats2 = psVectorAlloc(table2->numCols, PS_TYPE_U32);
+    out2 = psLookupTableInterpolateAll(table2, index2, stats2);
+
+    for(i=0; i<table2->numCols; i++) {
+        if(fabs(out2->data.F64[i]-truthData2[i])>FLT_EPSILON) {
+            printf("ERROR: Incorrect value, %lf. Expected %lf\n", out2->data.F64[i], truthData2[i]);
+        } else if(status1 != PS_LOOKUP_SUCCESS) {
+            printf("ERROR: Bad return status, %d for column %lld\n", stats2->data.U32[i], (long long int)i);
+        }
+    }
+    printFooter(stdout, "psMetadata", "Test B - Read table and interpolate all values", true);
+
+
+    // Test C - Read beyond lower table bound
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read beyond lower table bound");
+    psLookupStatusType status3 = 0;
+    psF64 index3 = 2451179.7;
+    psF64 out3 = 0.0;
+    psLookupTable* table3 = NULL;
+
+    table3 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table3 = psLookupTableRead(table3);
+    out3 = psLookupTableInterpolate(table3, index3, 0, &status3);
+    if(status3 != PS_LOOKUP_PAST_BOTTOM) {
+        printf("ERROR: Bad return status, %d\n", status3);
+    }
+    printFooter(stdout, "psMetadata", "Test C - Read beyond lower table bound", true);
+
+    // Test D - Read beyond upper table bound
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Read beyond upper table bound");
+    psLookupStatusType status4 = 0;
+    psF64 index4 = 0.0;
+    psF64 out4 = 0.0;
+    psLookupTable* table4 = NULL;
+
+    table4 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table4 = psLookupTableRead(table4);
+    out4 = psLookupTableInterpolate(table4, index4, 0, &status4);
+    if(status4 != PS_LOOKUP_PAST_TOP) {
+        printf("ERROR: Bad return status, %d\n", status4);
+    }
+    printFooter(stdout, "psMetadata", "Test D - Read beyond upper table bound", true);
+
+
+    // Test E - Free data
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Free data");
+    psFree(table1);
+    psFree(table2);
+    psFree(table3);
+    psFree(table4);
+    psFree(out2);
+    psFree(stats2);
+    if (psMemCheckLeaks(0, NULL, stdout, false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test E - Free data", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/dataIO/verified/tst_psFits.stderr
===================================================================
--- /branches/rel4/psLib/test/dataIO/verified/tst_psFits.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/verified/tst_psFits.stderr	(revision 3057)
@@ -0,0 +1,125 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsAlloc}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psFitsAlloc} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsMoveExtName}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    Could not find HDU 'bogus' in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    Specified extension name can not be NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsMoveExtName} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsMoveExtNum}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsGetSize (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move to specified HDU #-1 in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move -1 HDUs from current position in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move to specified HDU #8 in file multi.fits.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move 1 HDUs from current position in file multi.fits.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsMoveExtNum} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadHeader}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsReadHeader
+    following should be an error (input psFits = NULL)
+<DATE><TIME>|<HOST>|E|psFitsReadHeader (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadHeader} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadHeaderSet}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psFitsReadHeaderSet (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadHeaderSet} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadTable}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psFitsReadTable (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadTable} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadImage}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psFitsReadImage} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsWriteImage}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should generate an error message because input image is null.
+<DATE><TIME>|<HOST>|E|psFitsWriteImage (psFits.c:<LINENO>)
+    The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
+
+---> TESTPOINT PASSED (psImage{psFitsWriteImage} | tst_psFits.c)
+
Index: /branches/rel4/psLib/test/dataIO/verified/tst_psLookupTable_01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataIO/verified/tst_psLookupTable_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataIO/verified/tst_psLookupTable_01.stdout	(revision 3057)
@@ -0,0 +1,45 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test A - Read table and interpolate value}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test A - Read table and interpolate value} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test B - Read table and interpolate all values} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Read table and interpolate all values} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test C - Read beyond lower table bound}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Read beyond lower table bound} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test D - Read beyond upper table bound}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Read beyond upper table bound} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test E - Free data}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Free data} | tst_psLookupTable_01.c)
+
Index: /branches/rel4/psLib/test/dataManip/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/dataManip/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/.cvsignore	(revision 3057)
@@ -0,0 +1,55 @@
+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_psMatrixVectorArithmetic04
+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
+tst_psMinimize07
+tst_psRandom
Index: /branches/rel4/psLib/test/dataManip/Makefile
===================================================================
--- /branches/rel4/psLib/test/dataManip/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/Makefile	(revision 3057)
@@ -0,0 +1,87 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.54 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-12-21 23:24:49 $
+##
+##  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_psMatrixVectorArithmetic04 \
+tst_psMinimize04 \
+tst_psMinimize04_F32 \
+tst_psMinimize04b \
+tst_psMinimize04b_F32 \
+tst_psMinimize05 \
+tst_psMinimize06 \
+tst_psMinimize07 \
+tst_psStats00 \
+tst_psStats01 \
+tst_psStats02 \
+tst_psStats03 \
+tst_psStats05 \
+tst_psStats06 \
+tst_psStats07 \
+tst_psStats08 \
+tst_psStats09 \
+tst_psRandom \
+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/rel4/psLib/test/dataManip/tst_psFunc00.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc00.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc00.c	(revision 3057)
@@ -0,0 +1,640 @@
+/*****************************************************************************
+    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_X_CHEB_VALUE 0.5
+#define MISC_INT_NUMBER 35
+#define AN 2
+#define BN 4
+#define CN 6
+#define DN 8
+
+// XXX: This test comes from Paul Price.  We should add into the code.
+#define ORDER 3
+#define BAD 1
+int t01()
+{
+    psPolynomial1D *poly = psPolynomial1DAlloc(ORDER, PS_POLYNOMIAL_ORD);
+
+    for (int i = 0; i < poly->n; i++) {
+        poly->coeff[i] = (float)i;
+        if (i == BAD) {
+            poly->mask[i] = 1;  // Don't use this coefficient!
+        } else {
+            poly->mask[i] = 0;
+        }
+    }
+
+    fprintf(stderr,"Value using mask: %f\n", psPolynomial1DEval(poly, 0.5));
+
+    // A different method of doing the same thing
+    poly->coeff[BAD] = 0.0;
+    poly->mask[BAD] = 0;
+
+    fprintf(stderr,"Value using coefficient zeroing: %f\n", psPolynomial1DEval(poly, 0.5));
+
+    psFree(poly);
+
+    return(0);
+}
+
+
+psS32 main()
+{
+    t01();
+
+    psPolynomial1D *my1DPoly = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    psPolynomial3D *my3DPoly = NULL;
+    psPolynomial4D *my4DPoly = NULL;
+    psDPolynomial1D *my1DPolyD = NULL;
+    psDPolynomial2D *my2DPolyD = NULL;
+    psDPolynomial3D *my3DPolyD = NULL;
+    psDPolynomial4D *my4DPolyD = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 a               = 0;
+    psS32 b               = 0;
+    psS32 c               = 0;
+    psS32 d               = 0;
+    psS32 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(
+               my1DPoly,
+               MISC_X_VALUE
+           ));
+
+    psFree(my1DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my2DPoly,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my2DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my3DPoly,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my3DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my4DPoly,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my4DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my1DPolyD,
+               MISC_X_VALUE
+           ));
+
+    psFree(my1DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my2DPolyD,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my2DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my3DPolyD,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my3DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my4DPolyD,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE,
+               MISC_X_VALUE
+           ));
+
+    psFree(my4DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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(
+               my1DPoly,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my1DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           psPolynomial2DEval(
+               my2DPoly,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my2DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           MISC_X_CHEB_VALUE,
+           psPolynomial3DEval(
+               my3DPoly,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my3DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           MISC_X_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           psPolynomial4DEval(
+               my4DPoly,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my4DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE,
+           psDPolynomial1DEval(
+               my1DPolyD,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my1DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           psDPolynomial2DEval(
+               my2DPolyD,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my2DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           MISC_X_CHEB_VALUE,
+           psDPolynomial3DEval(
+               my3DPolyD,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my3DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           MISC_X_CHEB_VALUE, MISC_X_CHEB_VALUE,
+           psDPolynomial4DEval(
+               my4DPolyD,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE,
+               MISC_X_CHEB_VALUE
+           ));
+
+    psFree(my4DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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/rel4/psLib/test/dataManip/tst_psFunc01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc01.c	(revision 3057)
@@ -0,0 +1,76 @@
+/*****************************************************************************
+    This routine must ensure that the psGaussian() shall evaluate a
+    specified Gaussian at some X.
+ 
+    It also tests the p_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
+psS32 main()
+{
+    psS32 testStatus = true;
+    float x = 0.0;
+    psS32  memLeaks;
+    psS32  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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psGaussian()",
+                testStatus);
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "p_psGaussianDev()");
+
+    myGaussData = p_psGaussianDev(MY_MEAN, MY_STDEV, N);
+    for (psS32 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__,"p_psGaussianDev did not return a vector of type F32");
+    }
+
+    psFree(myGaussData);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "p_psGaussianDev()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psFunc02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc02.c	(revision 3057)
@@ -0,0 +1,438 @@
+/*****************************************************************************
+    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
+
+psS32 main()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32 i;
+    psS32  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+    psVector* bounds;
+
+    /****************************************************************************/
+    /****************************************************************************/
+    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]);
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, 1.0);
+
+    if (tmpSpline != NULL) {
+        printf("ERROR: allocated psSpline1D data structure when min==max\n");
+        testStatus = false;
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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]);
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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]);
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, 1.0);
+
+    if (tmpSpline != NULL) {
+        printf("ERROR: allocated psSpline1D data structure when min==max\n");
+        testStatus = false;
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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]);
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): cubic, min > max.",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): linear, normal");
+
+    bounds = psVectorAlloc(5,PS_TYPE_F32);
+    bounds->n = bounds->nalloc;
+    for(psU32 n = 0; n < 5; n++ ) {
+        bounds->data.F32[n] = (n+1) * 2;
+    }
+    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++) {
+        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+    }
+    psFree(bounds);
+    psFree(tmpSpline);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psError(PS_ERR_UNKNOWN,true,"Memory Leaks! (%d leaks)", memLeaks);
+        testStatus = false;
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): linear, normal",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): negative order");
+
+    bounds = psVectorAlloc(5,PS_TYPE_F32);
+    bounds->n = bounds->nalloc;
+    for(psU32 n = 0; n < 5; n++ ) {
+        bounds->data.F32[n] = (n+1) * 2;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    tmpSpline = psSpline1DAllocGeneric(bounds, -1);
+    if (tmpSpline != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return null for negative order");
+        return 10;
+    }
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psError(PS_ERR_UNKNOWN,true,"Memory Leaks! (%d leaks)", memLeaks);
+        testStatus = false;
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): negative order",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): bound equal to NULL");
+
+    bounds = NULL;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    tmpSpline = psSpline1DAllocGeneric(bounds, LINEAR);
+    if (tmpSpline != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return null for bounds equal to NULL");
+        return 20;
+    }
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psError(PS_ERR_UNKNOWN,true,"Memory Leaks! (%d leaks)", memLeaks);
+        testStatus = false;
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): bound equal to NULL",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): bounds with zero elements");
+
+    bounds = psVectorAlloc(5,PS_TYPE_F32);
+    bounds->n = 0;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    tmpSpline = psSpline1DAllocGeneric(bounds, LINEAR);
+    if (tmpSpline != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return null for negative order");
+        return 30;
+    }
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psError(PS_ERR_UNKNOWN,true,"Memory Leaks! (%d leaks)", memLeaks);
+        testStatus = false;
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): bounds with zero elements",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psFunc03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc03.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32 i;
+    psS32  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]);
+        }
+    }
+
+    psFree(tmpSpline);
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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]);
+        }
+    }
+
+    psFree(tmpSpline);
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): cubic",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psFunc04.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc04.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc04.c	(revision 3057)
@@ -0,0 +1,133 @@
+/*****************************************************************************
+    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
+
+psS32 t00()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32 i;
+    float x;
+    float y;
+    psS32  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;
+        }
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    psFree(data);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t01()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32 i;
+    float x;
+    float y;
+    psS32  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;
+        }
+    }
+
+    psFree(tmpSpline);
+    psMemCheckCorruption(1);
+    psFree(data);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t00();
+    //    t01();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psFunc05.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc05.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc05.c	(revision 3057)
@@ -0,0 +1,82 @@
+/*****************************************************************************
+    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
+
+psS32 main()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32 i;
+    psS32  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(
+            tmpSpline,
+            x
+        );
+
+    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;
+        }
+    }
+
+    psFree(tmpSpline);
+
+    psFree(x);
+    psFree(y);
+    psFree(data);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psFunc07.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psFunc07.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psFunc07.c	(revision 3057)
@@ -0,0 +1,181 @@
+/*****************************************************************************
+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))));
+}
+
+psS32 t00()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32  currentId = psMemGetId();
+    psS32 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(
+               tmpSpline,
+               newX
+           );
+
+    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);
+    psFree(tmpSpline);
+    psFree(newY);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    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.
+psS32 t01()
+{
+    psS32 testStatus = true;
+    psS32 memLeaks=0;
+    psS32  currentId = psMemGetId();
+    psS32 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(
+               tmpSpline,
+               newX
+           );
+
+    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);
+    psFree(tmpSpline);
+    psFree(newY);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(), psVectorFitSpline1D, psSpline1DEvalVector: F64 versions",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    //    t00();
+    t01();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psHist00.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psHist00.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psHist00.c	(revision 3057)
@@ -0,0 +1,125 @@
+/*****************************************************************************
+    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
+
+psS32 main()
+{
+    psHistogram *myHist = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 nb              = 0;
+    psS32 numBins         = 0;
+    psS32 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.F32[i] != 0.0) {
+                printf("ERROR: myHist->nums->data.U32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.F32[i] = 0.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)");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    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,false);
+    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/rel4/psLib/test/dataManip/tst_psHist01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psHist01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psHist01.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psHistogram *myHist = NULL;
+    psVector *myBounds  = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 nb              = 0;
+    psS32 numBins         = 0;
+    psS32 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.F32[i] != 0.0) {
+                printf("ERROR: myHist->nums->data.F32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.F32[i] = 0.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,false);
+    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/rel4/psLib/test/dataManip/tst_psHist02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psHist02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psHist02.c	(revision 3057)
@@ -0,0 +1,190 @@
+/*****************************************************************************
+   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
+
+psS32 main()
+{
+    psHistogram * myHist = NULL;
+    psHistogram *myHist2 = NULL;
+    psVector *myData = NULL;
+    psVector *myMask = NULL;
+    psS32 testStatus = true;
+    psS32 memLeaks = 0;
+    psS32 nb = 0;
+    psS32 numBins = 0;
+    psS32 i = 0;
+    psS32 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, NULL, 0 );
+
+        for ( i = 0;i < numBins;i++ ) {
+            printf( "Bin number %d bounds: (%.2f - %.2f) data (%f)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.F32[ 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, NULL, myMask, 1 );
+
+        for ( i = 0;i < numBins;i++ ) {
+            printf( "Bin number %d bounds: (%6.3f - %6.3f) data (%f)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.F32[ 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.
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    myHist2 = psVectorHistogram( NULL, myData, NULL, NULL, 0 );
+    if ( myHist2 != NULL ) {
+        printf( "ERROR: myHist2!=NULL\n" );
+        testStatus = false;
+    }
+    psFree( myData );
+
+
+    // ********************************************************************
+    // Verify the return 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 );
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    myHist = psVectorHistogram( myHist, NULL, NULL, NULL, 0 );
+    if ( myHist == NULL ) {
+        printf( "ERROR: myHist==NULL\n" );
+        testStatus = false;
+    }
+    psFree( myHist );
+
+
+    //    exit(0);
+    // ********************************************************************
+    // 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, 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,false);
+    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/rel4/psLib/test/dataManip/tst_psHist03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psHist03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psHist03.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psHistogram *myHist = NULL;
+    psVector *myBounds  = NULL;
+    psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 nb              = 0;
+    psS32 numBins         = 0;
+    psS32 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.F32[i] != 0.0) {
+                printf("ERROR: myHist->nums->data.F32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.F32[i] = 0.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, NULL, 0 );
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%6.3f - %6.3f): data: (%f)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.F32[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,false);
+    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/rel4/psLib/test/dataManip/tst_psMatrix01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix01.c	(revision 3057)
@@ -0,0 +1,131 @@
+/** @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.11 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 20:00:22 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE)                                                                                  \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psImage * tempImage = NULL;
+
+    double truthMatrix[3][3] = {{1, 4, 7},
+                                {2, 5, 8},
+                                {3, 6, 9}};
+
+    // 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;
+    psImage *inImageF32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    psImage *outImageF32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    inImageF32->data.F32[0][0] = 1;
+    inImageF32->data.F32[0][1] = 2;
+    inImageF32->data.F32[0][2] = 3;
+    inImageF32->data.F32[1][0] = 4;
+    inImageF32->data.F32[1][1] = 5;
+    inImageF32->data.F32[1][2] = 6;
+    inImageF32->data.F32[2][0] = 7;
+    inImageF32->data.F32[2][1] = 8;
+    inImageF32->data.F32[2][2] = 9;
+    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);
+    CHECK_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");
+    }
+
+    tempImage = outImageF32;
+    outImageF32 = psMatrixTranspose(outImageF32, inImageF32);
+    CHECK_MATRIX(outImageF32);
+    if (outImageF32->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if (outImageF32 != 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", "Transpose input image into auto allocated NULL output image");
+    psImage *outImageNull = NULL;
+    outImageNull = psMatrixTranspose(outImageNull, inImage);
+    CHECK_MATRIX(outImageNull);
+
+    psImage *outImageNullF32 = NULL;
+    outImageNullF32 = psMatrixTranspose(outImageNullF32, inImageF32);
+    CHECK_MATRIX(outImageNullF32);
+    printFooter(stdout, "psMatrix", "Transpose 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);
+    psFree(inImageF32);
+    psFree(outImageF32);
+    psFree(outImageNullF32);
+    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if (nLeaks != 0) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrix02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix02.c	(revision 3057)
@@ -0,0 +1,64 @@
+/** @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)  Incorrect type for output pointer
+ *     E)  Matrix not square for output pointer
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-09 22:50:39 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+psS32 main(psS32 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_C32);
+    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 - 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 E - 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/rel4/psLib/test/dataManip/tst_psMatrix03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix03.c	(revision 3057)
@@ -0,0 +1,221 @@
+/** @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.13 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2005-01-17 22:17:29 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE)                                                                                  \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+#define CHECK_VECTOR(VECTOR)                                                                                 \
+for(psU32 i=0; i<VECTOR->n; i++) {                                                                       \
+    if(VECTOR->type.type == PS_TYPE_F64) {                                                               \
+        if(fabs(VECTOR->data.F64[i]-truthVector[i]) > TOLERANCE) {                                       \
+            printf("Vector values at element %d don't agree %lf vs %lf\n", i,                            \
+                   VECTOR->data.F64[i], truthVector[i]);                                                 \
+        }                                                                                                \
+    } else if(VECTOR->type.type == PS_TYPE_F32){                                                         \
+        if(fabs(VECTOR->data.F32[i]-truthVector[i]) > TOLERANCE) {                                       \
+            printf("Vector values at element %d don't agree %f vs %lf\n", i,                             \
+                   VECTOR->data.F32[i], truthVector[i]);                                                 \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psImage *luImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+    psVector *tempVector = NULL;
+    psVector *perm = NULL;
+    psVector *outVector = NULL;
+    psVector *inVector = NULL;
+    psImage *luImage32 = NULL;
+    psImage *inImage32 = NULL;
+    psImage *tempImage32 = NULL;
+    psVector *tempVector32 = NULL;
+    psVector *perm32 = NULL;
+    psVector *outVector32 = NULL;
+    psVector *inVector32 = NULL;
+
+    double truthVector[3] = {
+                                4.000000,
+                                -2.000000,
+                                3.000000
+                            };
+
+    double truthMatrix[3][3] = {{4.000000,  5.000000,  6.000000},
+                                {0.750000, -2.750000, -6.500000},
+                                {0.500000, -0.545455, -0.545455}};
+
+
+    // 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;
+    luImage32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    outVector32 = (psVector*)psVectorAlloc(3, PS_TYPE_F32);
+    inVector32 = (psVector*)psVectorAlloc(3, PS_TYPE_F32);
+    inImage32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    inImage32->data.F32[0][0] =  2;
+    inImage32->data.F32[0][1] =  4;
+    inImage32->data.F32[0][2] =  6;
+    inImage32->data.F32[1][0] =  4;
+    inImage32->data.F32[1][1] =  5;
+    inImage32->data.F32[1][2] =  6;
+    inImage32->data.F32[2][0] =  3;
+    inImage32->data.F32[2][1] =  1;
+    inImage32->data.F32[2][2] = -2;
+    inVector32->data.F32[0] = 18.0;
+    inVector32->data.F32[1] = 24.0;
+    inVector32->data.F32[2] =  4.0;
+    inVector32->n = 3;
+    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);
+    CHECK_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");
+    }
+
+    tempImage32 = luImage32;
+    luImage32 = psMatrixLUD(luImage32, &perm32, inImage32);
+    CHECK_MATRIX(luImage32);
+    if(luImage32->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(luImage32 != tempImage32) {
+        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);
+    CHECK_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");
+    }
+
+    tempVector32 = outVector32;
+    outVector32 = psMatrixLUSolve(outVector32, luImage32, inVector32, perm32);
+    CHECK_VECTOR(outVector32);
+    if(outVector32->type.dimen != PS_DIMEN_VECTOR) {
+        printf("Error: Resulting image is not PS_DIMEN_VECTOR\n");
+    } else if(outVector32 != tempVector32) {
+        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);
+    psFree(inImage32);
+    psFree(luImage32);
+    psFree(perm32);
+    psFree(outVector32);
+    psFree(inVector32);
+    if( psMemCheckLeaks(0, NULL, stdout, false) ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 10;
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrix04.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix04.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix04.c	(revision 3057)
@@ -0,0 +1,163 @@
+/** @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.7 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-10 19:59:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE)                                                                                  \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+#define CHECK_VALUE(VALUE)                                                                                   \
+if(fabs(VALUE-truthValue) > TOLERANCE) {                                                                     \
+    printf("Values don't agree %lf vs %lf\n", VALUE, truthValue);                                            \
+}
+
+psS32 main(psS32 argc, char* argv[])
+{
+    float det = 0.0f;
+    float *det2 = NULL;
+    psImage *outImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+    psImage *outImage32 = NULL;
+    psImage *inImage32 = NULL;
+    psImage *tempImage32 = NULL;
+
+    double truthMatrix[3][3] = {{4.0000000, -4.333333, -2.333333},
+                                {-1.000000,  1.666667,  0.666667},
+                                {-1.000000,  0.666667,  0.666667}};
+    double truthValue = 3.0;
+
+
+    // 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;
+
+    outImage32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    inImage32 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    inImage32->data.F32[0][0] =  2;
+    inImage32->data.F32[0][1] =  4;
+    inImage32->data.F32[0][2] =  3;
+    inImage32->data.F32[1][0] =  0;
+    inImage32->data.F32[1][1] =  1;
+    inImage32->data.F32[1][2] = -1;
+    inImage32->data.F32[2][0] =  3;
+    inImage32->data.F32[2][1] =  5;
+    inImage32->data.F32[2][2] =  7;
+    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);
+    CHECK_MATRIX(outImage);
+    CHECK_VALUE(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");
+    }
+    det = 0.0f;
+    tempImage32 = outImage32;
+    outImage32 = psMatrixInvert(outImage32, inImage32, &det);
+    CHECK_MATRIX(outImage32);
+    CHECK_VALUE(det);
+    if(outImage32->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else if(outImage32 != tempImage32) {
+        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);
+    CHECK_VALUE(*det2);
+    psFree(det2);
+    det2 = psMatrixDeterminant(inImage32);
+    CHECK_VALUE(*det2);
+    psFree(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(outImage32);
+    psFree(inImage32);
+    if(psMemCheckLeaks(0, NULL, stdout, false) != 0 ) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrix05.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix05.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix05.c	(revision 3057)
@@ -0,0 +1,113 @@
+/** @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.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 20:54:34 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE)                                                                                  \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+
+psS32 main( psS32 argc,
+            char* argv[] )
+{
+    psImage * outImage = NULL;
+    psImage *inImage1 = NULL;
+    psImage *inImage2 = NULL;
+    psImage * outImage32 = NULL;
+    psImage *inImage132 = NULL;
+    psImage *inImage232 = NULL;
+
+    double truthMatrix[3][3] = {{ 8.000000, 20.000000},
+                                {-4.000000, 11.000000}};
+
+
+
+
+    // 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;
+    outImage32 = (psImage*)psImageAlloc(2, 2, PS_TYPE_F32);
+    inImage132 = (psImage*)psImageAlloc(2, 2, PS_TYPE_F32);
+    inImage232 = (psImage*)psImageAlloc(2, 2, PS_TYPE_F32);
+    inImage132->data.F32[0][0] = 2;
+    inImage132->data.F32[0][1] = 3;
+    inImage132->data.F32[1][0] = -1;
+    inImage132->data.F32[1][1] = 2;
+    inImage232->data.F32[0][0] = 4;
+    inImage232->data.F32[0][1] = 1;
+    inImage232->data.F32[1][0] = 0;
+    inImage232->data.F32[1][1] = 6;
+    printFooter( stdout, "psMatrix", "Create input and output images", true );
+
+
+    // Test B - Multiply images
+    printPositiveTestHeader(stdout, "psMatrix", "Multiply images");
+    psMatrixMultiply(outImage, inImage1, inImage2);
+    CHECK_MATRIX(outImage);
+    psMatrixMultiply(outImage32, inImage132, inImage232);
+    CHECK_MATRIX(outImage32);
+    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);
+    psFree(outImage32);
+    psFree(inImage132);
+    psFree(inImage232);
+    psS32 nLeaks = psMemCheckLeaks( 0, NULL, stdout, false );
+    if ( nLeaks != 0 ) {
+        printf( "ERROR: Found %d memory leaks\n", nLeaks );
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrix06.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix06.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix06.c	(revision 3057)
@@ -0,0 +1,124 @@
+/** @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.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-10 21:06:26 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE)                                                                                  \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-truthMatrix[i][j]) > TOLERANCE) {                              \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], truthMatrix[i][j]);                                        \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psImage * outImage = NULL;
+    psImage *inImage = NULL;
+    psImage * outImage32 = NULL;
+    psImage *inImage32 = NULL;
+
+    double truthMatrix[4][4] = {{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}};
+
+
+    // 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.;
+
+    outImage32 = (psImage*) psImageAlloc(4, 4, PS_TYPE_F32);
+    inImage32 = (psImage*)  psImageAlloc(4, 4, PS_TYPE_F32);
+    inImage32->data.F32[0][0] = 1./1.;
+    inImage32->data.F32[0][1] = 1./2.;
+    inImage32->data.F32[0][2] = 1./3.;
+    inImage32->data.F32[0][3] = 1./4.;
+    inImage32->data.F32[1][0] = 1./2.;
+    inImage32->data.F32[1][1] = 1./3.;
+    inImage32->data.F32[1][2] = 1./4.;
+    inImage32->data.F32[1][3] = 1./5.;
+    inImage32->data.F32[2][0] = 1./3.;
+    inImage32->data.F32[2][1] = 1./4.;
+    inImage32->data.F32[2][2] = 1./5.;
+    inImage32->data.F32[2][3] = 1./6.;
+    inImage32->data.F32[3][0] = 1./4.;
+    inImage32->data.F32[3][1] = 1./5.;
+    inImage32->data.F32[3][2] = 1./6.;
+    inImage32->data.F32[3][3] = 1./7.;
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Calculate Eigenvectors
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate Eigenvectors");
+    psMatrixEigenvectors(outImage, inImage);
+    CHECK_MATRIX(outImage);
+    psMatrixEigenvectors(outImage32, inImage32);
+    CHECK_MATRIX(outImage32);
+    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);
+    psFree(outImage32);
+    psFree(inImage32);
+    psS32 nLeaks = psMemCheckLeaks(0, NULL, stdout, false);
+    if (nLeaks != 0) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrix07.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrix07.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrix07.c	(revision 3057)
@@ -0,0 +1,198 @@
+/** @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.8 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-10 22:55:17 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+
+#define TOLERANCE 0.000001
+
+#define CHECK_MATRIX(IMAGE,TRUTH)                                                                        \
+for(psU32 i=0; i<IMAGE->numRows; i++) {                                                                  \
+    for(psU32 j=0; j<IMAGE->numCols; j++) {                                                              \
+        if(IMAGE->type.type == PS_TYPE_F64) {                                                            \
+            if(fabs(IMAGE->data.F64[i][j]-TRUTH[i][j]) > TOLERANCE) {                                    \
+                printf("Matrix values at element %d, %d don't agree %lf vs %lf\n", i, j,                 \
+                       IMAGE->data.F64[i][j], TRUTH[i][j]);                                              \
+            }                                                                                            \
+        } else if(IMAGE->type.type == PS_TYPE_F32){                                                      \
+            if(fabs(IMAGE->data.F32[i][j]-TRUTH[i][j]) > TOLERANCE) {                                    \
+                printf("Matrix values at element %d, %d don't agree %f vs %lf\n", i, j,                  \
+                       IMAGE->data.F32[i][j], TRUTH[i][j]);                                              \
+            }                                                                                            \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+#define CHECK_VECTOR(VECTOR)                                                                                 \
+for(psU32 i=0; i<VECTOR->n; i++) {                                                                       \
+    if(VECTOR->type.type == PS_TYPE_F64) {                                                               \
+        if(fabs(VECTOR->data.F64[i]-truthVector[i]) > TOLERANCE) {                                       \
+            printf("Vector values at element %d don't agree %lf vs %lf\n", i,                            \
+                   VECTOR->data.F64[i], truthVector[i]);                                                 \
+        }                                                                                                \
+    } else if(VECTOR->type.type == PS_TYPE_F32){                                                         \
+        if(fabs(VECTOR->data.F32[i]-truthVector[i]) > TOLERANCE) {                                       \
+            printf("Vector values at element %d don't agree %f vs %lf\n", i,                             \
+                   VECTOR->data.F32[i], truthVector[i]);                                                 \
+        }                                                                                                \
+    }                                                                                                    \
+}
+
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psVector *v1 = NULL;
+    psVector *tempVector = NULL;
+    psImage *tempImage = NULL;
+    psImage *m1 = NULL;
+    psVector *v2 = NULL;
+    psVector *v3 = NULL;
+    psImage *m2 = NULL;
+    psImage *m3 = NULL;
+    psImage *m4 = NULL;
+    psImage *badImage = NULL;
+
+    double truthVector[3] = {0.0, 1.0, 2.0};
+    double truthMatrix[3][1] = {{0.0}, {1.0}, {2.0}};
+
+    // 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;
+    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);
+    CHECK_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");
+    v3 = psVectorAlloc(3, PS_TYPE_F64);
+    v3->type.dimen = PS_DIMEN_TRANSV;
+    psMatrixToVector(v3, m4);
+    CHECK_VECTOR(v3);
+    if(v3->type.dimen != PS_DIMEN_TRANSV) {
+        printf("Error: Resulting image is not PS_DIMEN_TRANSV\n");
+    } else if(v3 != 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);
+    CHECK_MATRIX(m2,truthMatrix);
+    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);
+    CHECK_MATRIX(m3, truthMatrix);
+    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(v3);
+    psFree(m3);
+    psFree(m4);
+    psFree(badImage);
+    if( psMemCheckLeaks(0, NULL, stdout, false) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");
+        return 10;
+    }
+    psS32 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/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c	(revision 3057)
@@ -0,0 +1,205 @@
+/** @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.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:02:51 $
+ *
+ *  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 ", (psS32)SCALAR->data.TYPE);                                                               \
+} else {                                                                                                 \
+    printf("%f ", (double)SCALAR->data.TYPE);                                                            \
+}                                                                                                        \
+printf("\n\n");
+
+#define PRINT_VECTOR(VECTOR,TYPE)                                                                            \
+for(psS32 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 ", (psS32)VECTOR->data.TYPE[i]);                                                        \
+    } else {                                                                                             \
+        printf("%f ", (double)VECTOR->data.TYPE[i]);                                                     \
+    }                                                                                                    \
+}                                                                                                        \
+printf("\n\n");
+
+
+#define PRINT_MATRIX(IMAGE,TYPE)                                                                             \
+for(psS32 i=IMAGE->numRows-1; i>-1; i--) {                                                                 \
+    for(psS32 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 ", (psS32)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(psS32 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(psS32 i=0; i<NAME->numRows; i++) {                                                                     \
+    for(psS32 j=0; j<NAME->numCols; j++) {                                                                 \
+        NAME->data.TYPE[i][j] = VALUE;                                                                   \
+    }                                                                                                    \
+}
+
+
+#define CHECK_MEMORY                                                                                     \
+if(psMemCheckLeaks(0, NULL, stdout, false) != 0 ) {                                                             \
+    psError(PS_ERR_UNKNOWN,true,"Memory leaks detected.");                                                \
+    return 10;                                                                                            \
+}                                                                                                        \
+psS32 nBad = psMemCheckCorruption(0);                                                                    \
+if(nBad) {                                                                                               \
+    printf("ERROR: Found %d bad memory blocks\n", nBad);                                                 \
+}
+
+
+psS32 main(psS32 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/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c	(revision 3057)
@@ -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.9 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-22 21:02:51 $
+ *
+ *  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(psS32 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", (psS32)(VECTOR->data.TYPE[i]));                                              \
+            printf("Calculated: %d\n", (psS32)(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(psS32 i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(psS32 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", (psS32)(IMAGE->data.TYPE[i][j]));                                        \
+                printf("Calculated: %d\n", (psS32)(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(psS32 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(psS32 i=0; i<NAME->numRows; i++) {                                                                         \
+    for(psS32 j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+#define CHECK_MEMORY \
+if( psMemCheckLeaks(0, NULL, stdout, false) != 0 ) {  \
+    psError(PS_ERR_UNKNOWN, true,"Memory leaks detected."); \
+    return 50; \
+} \
+psS32 nBad = psMemCheckCorruption(0); \
+if(nBad) { \
+    psError(PS_ERR_UNKNOWN, true,"ERROR: Found %d bad memory blocks\n", nBad); \
+    return 51; \
+}
+
+
+psS32 main( psS32 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/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c	(revision 3057)
@@ -0,0 +1,314 @@
+/** @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.8 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-12-10 21:38:47 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_VECTOR(VECTOR,TYPE) \
+for(psS32 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 ", (psS32)VECTOR->data.TYPE[i]); \
+    } else { \
+        printf("%f ", (double)VECTOR->data.TYPE[i]); \
+    } \
+} \
+printf("\n\n");
+
+#define PRINT_MATRIX(IMAGE,TYPE) \
+for(psS32 i=IMAGE->numRows-1; i>-1; i--) { \
+    for(psS32 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 ", (psS32)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(psS32 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(psS32 i=0; i<NAME->numRows; i++) { \
+    for(psS32 j=0; j<NAME->numCols; j++) { \
+        NAME->data.TYPE[i][j] = VALUE; \
+    } \
+}
+
+
+psS32 main(psS32 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 output argument
+    printPositiveTestHeader(stdout,"psBinaryOp", "Check for output generated");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check for output generated",true);
+
+    // Check for NULL input argument #1
+    printPositiveTestHeader(stdout,"psBinaryOp","Check for null input arg 1");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check for null input arg 1",true);
+
+    // Check for NULL input argument #2
+    printPositiveTestHeader(stdout,"psBinaryOp","Check for null input arg 2");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check for null input arg 2",true);
+
+    // Check for NULL operand
+    printPositiveTestHeader(stdout,"psBinaryOp","Check for null operand");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check for null operand",true);
+
+    // Check for null output
+    printPositiveTestHeader(stdout,"psUnaryOp","Check for null output");
+    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;
+    }
+    printFooter(stdout,"psUnaryOp","Check for null output",true);
+
+    // Check for NULL input arg
+    printPositiveTestHeader(stdout,"psUnaryOp","Check for null input");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    image6 = (psImage*)psUnaryOp(image6, NULL, "sin");
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned a result given a NULL operand.");
+        return 6;
+    }
+    printFooter(stdout,"psUnaryOp","Check for null input",true);
+
+    // Check for NULL operand
+    printPositiveTestHeader(stdout,"psUnaryOp","Check for null operator");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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,"psUnaryOp","Check for null operator",true);
+
+    // Inconsistent element types
+    printPositiveTestHeader(stdout,"psBinaryOp", "Inconsistent element types");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Inconsistent element types",true);
+
+    // Check unary op to convert to correct type
+    printPositiveTestHeader(stdout,"psUnaryOp","Check output type conversion");
+    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,"psUnaryOp","Check output type conversion",true);
+
+    // Inconsistent element count
+    printPositiveTestHeader(stdout,"psBinaryOp","Check for inconsistent elements");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check for inconsistent elements",true);
+
+    // Inconsistent element in input and output
+    printPositiveTestHeader(stdout,"psUnaryOp","Check inconsistent elements in input and output");
+    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;
+    }
+    printFooter(stdout,"psUnaryOp","Check inconsistent elements in input and output",true);
+
+    // Inconsistent size of input 1 and input 2
+    printPositiveTestHeader(stdout,"psBinaryOp","Check inconsistent size");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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;
+    }
+    printFooter(stdout,"psBinaryOp","Check inconsistent size",true);
+
+    // Inconsistent size of input 1 and input 2
+    printPositiveTestHeader(stdout,"psBinaryOp","Check inconsistent size");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    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, "psBinaryOp", "Check inconsistent size", true);
+
+
+    // Inconsistent dimensionality
+    printPositiveTestHeader(stdout,"psUnaryOp","Check inconsistent dimensionality");
+    image6 = psImageCopy(image6,image2,PS_TYPE_F64);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an two error messages");
+    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,"psUnaryOp","Check inconsistent dimensionality",true);
+
+    // Attempt to use min with complex numbers
+    printPositiveTestHeader(stdout,"psBinaryOp","Attempt to use min with complex numbers");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error message");
+    image6 = (psImage*)psBinaryOp(image6, image5, "min", image5);
+    if(image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned result with min of complex numbers");
+        return 15;
+    }
+    printFooter(stdout, "psBinaryOp", "Attempt to use  min with complex numbers", true);
+
+
+    // Attempt to use max with complex numbers
+    printPositiveTestHeader(stdout,"psBinaryOp","Attempt to use max with complex numbers");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    image6 = (psImage*)psBinaryOp(image6, image5, "max", image5);
+    if(image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned result with max of complex numbers");
+        return 16;
+    }
+    printFooter(stdout, "psBinaryOp", "Attempt to use max with complex numbers", true);
+
+
+    // Invalid operation
+    printPositiveTestHeader(stdout,"psBinary","Attempt to use invalid operator");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error messgae");
+    image6 = (psImage*)psBinaryOp(image6, image1, "yarg", image2);
+    if(image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned result with invalid operator");
+        return 17;
+    }
+    printFooter(stdout,"psBinaryOp","Attempt to use invalid operator",true);
+
+    printPositiveTestHeader(stdout,"psUnaryOp","Attempt to use invalid operator");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    image6 = (psImage*)psUnaryOp(image6, image1, "yarg");
+    if(image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned result with invalid operator");
+        return 18;
+    }
+    printFooter(stdout, "psUnaryOp", "Attempt to use invalid operator", true);
+
+    CREATE_AND_SET_VECTOR(vector4,F64,0,3);
+    CREATE_AND_SET_VECTOR(vector5,F64,0,3);
+
+    // Input parameter with dimension of PS_DIMEN_OTHER
+    printPositiveTestHeader(stdout,"psBinaryOp","Attempt to use input with PS_DIMEN_OTHER");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    vector4->type.dimen = PS_DIMEN_OTHER;
+    if ( psBinaryOp(NULL,vector4,"+",vector5) != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psBinaryOp should return null when input dimen PS_DIMEN_OTHER.");
+        return 19;
+    }
+    vector4->type.dimen = PS_DIMEN_VECTOR;
+    printFooter(stdout,"psBinaryOp","Attempt to use input with PS_DIMEN_OTHER",true);
+
+    // Input parameter with dimension of PS_DIMEN_OTHER
+    printPositiveTestHeader(stdout,"psUnaryOp","Attempt to use input with PS_DIMEN_OTHER");
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    vector4->type.dimen = PS_DIMEN_OTHER;
+    if ( psUnaryOp(NULL,vector4,"sin") != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psUnaryOp should return null when input dimen PS_DIMEN_OTHER");
+        return 20;
+    }
+    vector4->type.dimen = PS_DIMEN_VECTOR;
+    printFooter(stdout,"psUnaryOp","Attempt to use input with PS_DIMEN_OTHER",true);
+
+    psFree(vector4);
+    psFree(vector5);
+    psFree(image1);
+    psFree(image2);
+    psFree(image3);
+    psFree(image4);
+    psFree(image5);
+    psFree(vector1);
+    psFree(vector2);
+
+    psS32 nLeaks = psMemCheckLeaks(0,NULL,stdout,false);
+    if(nLeaks != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 50;
+    }
+    psS32 nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        psError(PS_ERR_UNKNOWN,true,"Memory corruption detected");
+        return 51;
+    }
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic04.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic04.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMatrixVectorArithmetic04.c	(revision 3057)
@@ -0,0 +1,212 @@
+/** @file  tst_psMatrixVectorArithmetic04.c
+ *
+ *  @brief Test driver for psBinary arithmetic operations with scalars
+ *
+ *  This test driver will test the following binary operation with scalar inputs
+ *        vector addition with scalar in first argument
+ *        image addition with scalar in second argument
+ *
+ * @author  Eric Van Alst, MHPCC
+ *
+ * @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ * @date  $Date: 2004-12-11 03:05:54 $
+ *
+ * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+static psS32 testBinOpScalarFirst(void);
+static psS32 testBinOpScalarSecond(void);
+static psS32 testBinOpScalarBoth(void);
+static psS32 testUnaryOpScalar(void);
+
+testDescription testsBinary[] = {
+                                    {testBinOpScalarFirst,737,"psBinaryOp",0,false},
+                                    {testBinOpScalarSecond,737,"psBinaryOp",0,false},
+                                    {testBinOpScalarBoth,737,"psBinaryOp",0,false},
+                                    {NULL}
+                                };
+
+testDescription testUnary[] = {
+                                  {testUnaryOpScalar,737,"psUnaryOp",0,false},
+                                  {NULL}
+                              };
+
+// Create vector
+#define CREATE_AND_SET_VECTOR(NAME,TYPE,VALUE,SIZE) \
+psVector *NAME = psVectorAlloc(SIZE,PS_TYPE_##TYPE); \
+for(psS32 i=0; i<SIZE; i++) { \
+    NAME->data.TYPE[i] = VALUE; \
+} \
+NAME->n = SIZE;
+
+// Create image
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS) \
+psImage *NAME = psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE); \
+for(psS32 i=0; i<NAME->numRows; i++) { \
+    for(psS32 j=0; j<NAME->numCols; j++) { \
+        NAME->data.TYPE[i][j] = VALUE; \
+    } \
+}
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    runTestSuite(stderr,"psBinaryOp",testsBinary,argc,argv);
+    runTestSuite(stderr,"psUnaryOp",testUnary,argc,argv);
+
+    return 0;
+}
+
+psS32 testBinOpScalarFirst(void)
+{
+    CREATE_AND_SET_VECTOR(vector1,S8,1,5)
+    CREATE_AND_SET_VECTOR(vector2,S8,0,5)
+
+    psScalar* inScalar1 = psScalarAlloc(2,PS_TYPE_S8);
+
+    // Add vector and scalar
+    vector2 = (psVector*)psBinaryOp(vector2,inScalar1,"+",vector1);
+    // Verify the result vector
+    for(psS32 i=0; i<vector2->n; i++) {
+        if(vector2->data.S8[i] != 3 ) {
+            psError(PS_ERR_UNKNOWN,true,"Unexpected value in return vector[%d]",i);
+            return 1;
+        }
+    }
+    psFree(vector1);
+    psFree(vector2);
+
+    CREATE_AND_SET_VECTOR(vector3,S8,1,5);
+    CREATE_AND_SET_VECTOR(vector4,S8,0,3);
+
+    psScalar* inScalar2 = psScalarAlloc(2,PS_TYPE_S8);
+    vector4->type.dimen = PS_DIMEN_TRANSV;
+    vector4 = (psVector*)psBinaryOp(vector4,inScalar2,"+",vector3);
+    for(psS32 i=0; i<vector4->n; i++) {
+        if(vector4->data.S8[i] != 3 ) {
+            psError(PS_ERR_UNKNOWN,true,"Unexpected value in return vector[%d]",i);
+            return 2;
+        }
+    }
+    psFree(vector3);
+    psFree(vector4);
+
+    CREATE_AND_SET_IMAGE(image1,S8,1,5,5)
+    psImage* image2 = NULL;
+
+    psScalar* inScalar3 = psScalarAlloc(2,PS_TYPE_S8);
+
+    image2 = (psImage*)psBinaryOp(image2,inScalar3,"+",image1);
+    for(psS32 i=0; i<image2->numRows; i++) {
+        for(psS32 j=0; j<image2->numCols; j++) {
+            if(image2->data.S8[i][j] != 3 ) {
+                psError(PS_ERR_UNKNOWN,true,"Unexpected value in return image[%d][%d]",i,j);
+                return 10;
+            }
+        }
+    }
+    psFree(image1);
+    psFree(image2);
+
+    return 0;
+}
+
+psS32 testBinOpScalarSecond(void)
+{
+    CREATE_AND_SET_VECTOR(vector1,S8,1,5)
+    CREATE_AND_SET_VECTOR(vector2,S8,0,5)
+
+    psScalar* inScalar1 = psScalarAlloc(2,PS_TYPE_S8);
+
+    vector2 = (psVector*)psBinaryOp(vector2,vector1,"+",inScalar1);
+    for(psS32 i=0; i<vector2->n; i++) {
+        if(vector2->data.S8[i] != 3 ) {
+            psError(PS_ERR_UNKNOWN,true,"Unexpected value in return vector[%d]",i);
+            return 1;
+        }
+    }
+    psFree(vector1);
+    psFree(vector2);
+
+    CREATE_AND_SET_VECTOR(vector3,S8,1,5);
+    CREATE_AND_SET_VECTOR(vector4,S8,0,3);
+
+    psScalar* inScalar2 = psScalarAlloc(2,PS_TYPE_S8);
+    vector4->type.dimen = PS_DIMEN_TRANSV;
+    vector4 = (psVector*)psBinaryOp(vector4,vector3,"+",inScalar2);
+    for(psS32 i=0; i<vector4->n; i++) {
+        if(vector4->data.S8[i] != 3 ) {
+            psError(PS_ERR_UNKNOWN,true,"Unexpected value in return vector[%d]",i);
+            return 2;
+        }
+    }
+    psFree(vector3);
+    psFree(vector4);
+
+    CREATE_AND_SET_IMAGE(image1,S8,1,5,5);
+    psImage* image2 = NULL;
+
+    psScalar* inScalar3 = psScalarAlloc(2,PS_TYPE_S8);
+
+    image2 = (psImage*)psBinaryOp(image2,image1,"+",inScalar3);
+    for(psS32 i=0; i<image2->numRows; i++) {
+        for(psS32 j=0; j<image2->numCols; j++) {
+            if(image2->data.S8[i][j] != 3 ) {
+                psError(PS_ERR_UNKNOWN,true,"Unexpected value in return image[%d][%d]",i,j);
+                return 10;
+            }
+        }
+    }
+    psFree(image1);
+    psFree(image2);
+
+    return 0;
+}
+
+psS32 testBinOpScalarBoth(void)
+{
+    psScalar* inScalar1 = psScalarAlloc(1,PS_TYPE_S8);
+    psScalar* inScalar2 = psScalarAlloc(2,PS_TYPE_S8);
+    psScalar* outScalar = psScalarAlloc(4,PS_TYPE_S8);
+
+    outScalar = (psScalar*)psBinaryOp(outScalar,inScalar1,"+",inScalar2);
+    if(outScalar->data.S8 != 3) {
+        psError(PS_ERR_UNKNOWN,true,"Unexpected value in return scalar");
+        return 3;
+    }
+    psFree(outScalar);
+
+    psScalar* inScalar3 = psScalarAlloc(10,PS_TYPE_S8);
+    psScalar* inScalar4 = psScalarAlloc(20,PS_TYPE_S8);
+    psScalar* outScalar1 = NULL;
+
+    outScalar1 = (psScalar*)psBinaryOp(outScalar1,inScalar3,"+",inScalar4);
+    if(outScalar1->data.S8 != 30 ) {
+        psError(PS_ERR_UNKNOWN,true,"Unexpected value in return scalar");
+        return 4;
+    }
+    psFree(outScalar1);
+
+    return 0;
+}
+
+psS32 testUnaryOpScalar(void)
+{
+    psScalar* inScalar = psScalarAlloc(-1,PS_TYPE_F32);
+    psScalar* outScalar = NULL;
+
+    outScalar = (psScalar*)psUnaryOp(outScalar,inScalar,"abs");
+    if(outScalar->data.F32 != 1) {
+        psError(PS_ERR_UNKNOWN,true,"Unexpected value in return scalar = %d  in = %d",outScalar->data.F32,inScalar->data.F32);
+        return 5;
+    }
+    psFree(outScalar);
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize00.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize00.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize00.c	(revision 3057)
@@ -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,
+                  psS32 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);
+}
+
+
+psS32 main()
+{
+    psImage *domain = NULL;
+    psVector *data = NULL;
+    psVector *errors = NULL;
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *tmpVecPtr = NULL;
+    float chiSq = 0.0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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/rel4/psLib/test/dataManip/tst_psMinimize01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize01.c	(revision 3057)
@@ -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,
+                  psS32 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);
+}
+
+psS32 main()
+{
+    psImage *domain = NULL;
+    psVector *data = NULL;
+    psVector *errors = NULL;
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *tmpVecPtr = NULL;
+    float chiSq = 0.0;
+    psS32 i = 0;
+    psVector *theParams = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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/rel4/psLib/test/dataManip/tst_psMinimize02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize02.c	(revision 3057)
@@ -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,
+                   psS32 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,
+                  psS32 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);
+}
+
+
+psS32 main()
+{
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *coord = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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/rel4/psLib/test/dataManip/tst_psMinimize03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize03.c	(revision 3057)
@@ -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,
+                   psS32 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,
+                  psS32 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);
+}
+
+
+psS32 main()
+{
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *coord = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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/rel4/psLib/test/dataManip/tst_psMinimize04.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize04.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize04.c	(revision 3057)
@@ -0,0 +1,274 @@
+/*****************************************************************************
+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));
+}
+
+psS32 t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         x->data.F64[i]
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): equal differences in variable yErr",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         x->data.F64[i]
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         (double) i
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): x, yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t03()
+{
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(PS_ERR_UNKNOWN, true,"A null polynomial should have returned a null pointer.");
+        testStatus = false;
+    }
+
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): all inputs are NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+
+psS32 main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize04_F32.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize04_F32.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize04_F32.c	(revision 3057)
@@ -0,0 +1,268 @@
+/*****************************************************************************
+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));
+}
+
+psS32 t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         x->data.F32[i]
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): equal errors in yErr",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         x->data.F32[i]
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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(
+                         myPoly,
+                         (float) i
+                     );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): x, yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+psS32 t03()
+{
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): all inputs are NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+
+psS32 main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize04b.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize04b.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize04b.c	(revision 3057)
@@ -0,0 +1,259 @@
+/*****************************************************************************
+    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 21
+#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));
+}
+
+psS32 t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF64(x, -1.0, 1.0);
+
+    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(
+                                myPoly,
+                                x->data.F64[i]
+                            );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, equal errors in yErr",
+                testStatus);
+    return (!testStatus);
+}
+
+
+psS32 t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF64(x, -1.0, 1.0);
+
+    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(
+                                myPoly,
+                                x->data.F64[i]
+                            );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+
+psS32 t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF64(x, -1.0, 1.0);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, NULL, y, 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(myPoly, x->data.F64[i]);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.2f %.2f), expected was (%.2f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Remove for testing since print out differs from platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.2f %.2f), expected was (%.2f)\n",
+        //                   i, x->data.F64[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+psS32 t03()
+{
+    psPolynomial1D *myPoly = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize04b_F32.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize04b_F32.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize04b_F32.c	(revision 3057)
@@ -0,0 +1,261 @@
+/*****************************************************************************
+    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));
+}
+
+psS32 t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF32(x, -1.0f, 1.0f);
+
+    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(
+                               myPoly,
+                               x->data.F32[i]
+                           );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, equal errors in yErr",
+                testStatus);
+    return (!testStatus);
+}
+
+
+psS32 t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF32(x, -1.0f, 1.0f);
+
+    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(
+                               myPoly,
+                               x->data.F32[i]
+                           );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+
+psS32 t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psS32 i = 0;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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_psNormalizeVectorRangeF32(x, -1.0, 1.0);
+
+    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(
+                                myPoly,
+                                x->data.F32[i]
+                            );
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+psS32 t03()
+{
+    psPolynomial1D *myPoly = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 testStatus = true;
+    psS32 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize05.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize05.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize05.c	(revision 3057)
@@ -0,0 +1,279 @@
+/*****************************************************************************
+    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];
+psS32 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;
+    psS32 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);
+}
+
+
+psS32 t00()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 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_U8);
+    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;
+        myParams->data.F32[i] = (float) i;
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell()",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+psS32 t01()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 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;
+        myParams->data.F32[i] = (float) i;
+    }
+
+    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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell()",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+psS32 t02()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 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_U8);
+    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;
+        myParams->data.F32[i] = (float) i;
+        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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell(): various NULL inputs",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t00();
+    t01();
+    t02();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize06.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize06.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize06.c	(revision 3057)
@@ -0,0 +1,120 @@
+/*****************************************************************************
+    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 20
+#define MIN_VALUE 5.0
+#define NUM_PARAMS 3
+float expectedParm[NUM_PARAMS];
+psS32 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().
+ 
+ *****************************************************************************/
+psVector *myFunc(psImage *myDeriv,
+                 psVector *myParams,
+                 psArray *myCoords)
+{
+    psVector *sum = psVectorAlloc(myCoords->n, PS_TYPE_F32);
+    psS32 i;
+    psS32 j;
+
+
+    if (myDeriv == NULL) {
+        myDeriv = psImageAlloc(myParams->n, myCoords->n, PS_TYPE_F32);
+        psError(PS_ERR_UNKNOWN, true, "myDeriv is NULL.\n");
+    }
+
+    for (i=0;i<N;i++) {
+        sum->data.F32[i] = MIN_VALUE;
+        for (j=0;j<NUM_PARAMS;j++) {
+            sum->data.F32[i]+= (myParams->data.F32[j] - expectedParm[j]) *
+                               (myParams->data.F32[j] - expectedParm[j]);
+
+            myDeriv->data.F32[i][j] = (2.0 * myParams->data.F32[j]) -
+                                      (2.0 * expectedParm[j]);
+        }
+    }
+
+    return(sum);
+}
+
+psS32 t01()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psImage *myCovar;
+    psMinimization *min;
+    psVector *y;
+
+    psTraceSetLevel(".psLib", 0);
+    /**************************************************************************
+     *************************************************************************/
+    min = psMinimizationAlloc(NUM_ITERATIONS, ERR_TOL);
+    myCovar = psImageAlloc(NUM_PARAMS, NUM_PARAMS, PS_TYPE_F32);
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myCoords = psArrayAlloc(N);
+    y = psVectorAlloc(N, PS_TYPE_F32);
+
+    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);
+        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;
+    }
+
+    psMinimizeLMChi2(min,
+                     myCovar,
+                     myParams,
+                     NULL,
+                     myCoords,
+                     y,
+                     NULL,
+                     (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(min);
+    psFree(myCovar);
+    psFree(myParams);
+    psFree(myCoords);
+    psFree(y);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t01();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psMinimize07.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psMinimize07.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psMinimize07.c	(revision 3057)
@@ -0,0 +1,164 @@
+/*****************************************************************************
+    This routine must ensure that psMinimizeLMChi2Gauss1D() works correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include <math.h>
+#define NUM_ITERATIONS 100
+#define ERR_TOL 0.0
+#define N 24
+#define NUM_PARAMS 2
+#define MEAN 14.5
+#define STDEV 1.2
+
+float expectedParm[NUM_PARAMS];
+psS32 testStatus = true;
+
+// This routine generates a vector of length "n" with the specified mean and
+// stdev.
+psVector *genGaussianVector(int n, float mean, float stdev)
+{
+    psVector *y = psVectorAlloc(n, PS_TYPE_F32);
+
+    for (psS32 i=0;i<n;i++) {
+        y->data.F32[i] = psGaussian((float) i, mean, stdev, false);
+    }
+    return(y);
+}
+
+// This routine tries to fit a Gaussian to a set of data points via the
+// psMinimizeLMChi2() and psMinimizeLMChi2Gauss1D() functions.
+psS32 t00()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psImage *myCovar;
+    psMinimization *min;
+
+    psTraceSetLevel(".psLib.dataManip.psMinimize", 0);
+    /**************************************************************************
+     *************************************************************************/
+    min = psMinimizationAlloc(NUM_ITERATIONS, ERR_TOL);
+    myCovar = psImageAlloc(NUM_PARAMS, NUM_PARAMS, PS_TYPE_F32);
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myParams->data.F32[0] = MEAN * 0.7;
+    myParams->data.F32[1] = STDEV * 0.7;
+    myCoords = psArrayAlloc(N);
+    psVector *y = genGaussianVector(N, MEAN, STDEV);
+
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) i;
+        printf("Initial data %d: (%f, %f)\n", i, ((psVector *) (myCoords->data[i]))->data.F32[0], y->data.F32[i]);
+    }
+
+    psMinimizeLMChi2(min,
+                     myCovar,
+                     myParams,
+                     NULL,
+                     myCoords,
+                     y,
+                     NULL,
+                     (psMinimizeLMChi2Func) psMinimizeLMChi2Gauss1D);
+
+    printf("\nThe chi-squared is %f\n", min->value);
+
+    expectedParm[0] = MEAN;
+    expectedParm[1] = STDEV;
+    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(min);
+    psFree(myCovar);
+    psFree(myParams);
+    psFree(myCoords);
+    psFree(y);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    return (!testStatus);
+}
+
+// This routine tries to fit a Gaussian to a set of data points via the
+// psMinimizeChi2Powell() function.
+psS32 t01()
+{
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psS32 i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psImage *myCovar;
+    psMinimization *min;
+
+    psTraceSetLevel(".psLib.dataManip.psMinimize", 0);
+    psTraceSetLevel(".psLib.dataManip.psMinimizeLMChi2Gauss1D", 0);
+
+    psTraceSetLevel(".psLib.dataManip.psMinimizePowell", 0);
+    psTraceSetLevel(".psLib.dataManip.myPowellChi2Func", 0);
+    psTraceSetLevel(".psLib.dataManip.p_psLineMin", 0);
+    psTraceSetLevel(".psLib.dataManip.p_psDetermineBracket", 0);
+    psTraceSetLevel(".psLib.dataManip.psFunctions.psGaussian", 0);
+    psTraceSetLevel(".psLib.dataManip.psFunctions", 0);
+    psTraceSetLevel(".", 0);
+    //    psTracePrintLevels();
+    /**************************************************************************
+     *************************************************************************/
+    min = psMinimizationAlloc(NUM_ITERATIONS, ERR_TOL);
+    myCovar = psImageAlloc(NUM_PARAMS, NUM_PARAMS, PS_TYPE_F32);
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myParams->data.F32[0] = MEAN * 0.7;
+    myParams->data.F32[1] = STDEV * 0.7;
+    myCoords = psArrayAlloc(N);
+    psVector *y = genGaussianVector(N, MEAN, STDEV);
+
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPtr *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) i;
+        printf("Initial data %d: (%f, %f)\n", i, ((psVector *) (myCoords->data[i]))->data.F32[0], y->data.F32[i]);
+    }
+
+    //    psMinimizeChi2Powell(min, myParams, NULL, myCoords, y, NULL,
+    //                         (psMinimizeChi2PowellFunc) myFunc);
+    psMinimizeChi2Powell(min, myParams, NULL, myCoords, y, NULL,
+                         (psMinimizeChi2PowellFunc) psMinimizePowellChi2Gauss1D);
+
+    printf("\nThe chi-squared is %f\n", min->value);
+
+    expectedParm[0] = MEAN;
+    expectedParm[1] = STDEV;
+    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(min);
+    psFree(myCovar);
+    psFree(myParams);
+    psFree(myCoords);
+    psFree(y);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    return (!testStatus);
+}
+
+psS32 main()
+{
+    t00();
+    t01();
+}
+//This code is
+
Index: /branches/rel4/psLib/test/dataManip/tst_psRandom.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psRandom.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psRandom.c	(revision 3057)
@@ -0,0 +1,478 @@
+/*****************************************************************************
+This routine must ensure that the various random number generator functions
+work properly.
+ 
+    t00(): ensure that psRandom structs are properly allocated by psRandomAlloc().
+    t01(): ensure that psRandomUniform() produces a sequence of numbers with
+    proper mean and stdev.
+    t02(): ensure that psRandomGaussian() produces a sequence of numbers with
+    proper mean and stdev.
+    t03(): ensure that psRandomPoisson() produces a sequence of numbers with
+    proper mean and stdev.
+    t04(): ensure that psRandomReset() properly seeds the random number
+    generator for psRandomUniform().
+    t05(): ensure that psRandomReset() properly seeds the random number
+    generator for psRandomGaussian().
+    t06(): ensure that psRandomReset() properly seeds the random number
+    generator for psRandomPoisson().
+ *****************************************************************************/
+#include <stdio.h>
+#include <math.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psRandom.h"
+#define NUM_DATA 10000
+#define SEED 54321
+#define SEED2 345
+#define UNIFORM_MEAN 0.5
+#define UNIFORM_STDEV 0.3
+#define GAUSSIAN_MEAN 0.0
+#define GAUSSIAN_STDEV 1.0
+#define POISSON_MEAN 15.0
+#define POISSON_STDEV (POISSON_MEAN / 4)
+#define ERROR_TOLERANCE 0.1
+psS32 testStatus = true;
+
+psS32 t00()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc()");
+
+    // Valid type allocation
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+    if (myRNG->type != PS_RANDOM_TAUS) {
+        psError(PS_ERR_UNKNOWN,true,"Did not have the expected type");
+        testStatus = false;
+    }
+    psFree(myRNG);
+
+    // Valid type allocation with seed equal to zero
+    psLogSetDestination("file:seed_msglog1.txt");
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, 0);
+    psLogSetDestination("dest:stderr");
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+    if (myRNG->type != PS_RANDOM_TAUS) {
+        psError(PS_ERR_UNKNOWN,true,"Did not have the expected type");
+        testStatus = false;
+    }
+    psFree(myRNG);
+
+    // Invalid type allocation
+    psLogMsg(__func__,PS_LOG_INFO,"Invalid type, should generate error message");
+    myRNG = psRandomAlloc(100,SEED);
+    if (myRNG != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL for invalid type");
+        testStatus = false;
+    }
+
+    // Negative seed value
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS,-5);
+    if(myRNG == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return allocated psRandom");
+        testStatus = false;
+    }
+    psFree(myRNG);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        printf("ERROR: Memory Leaks! (%d leaks)", memLeaks);
+        testStatus = false;
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t01()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc() and psRandomUniform()");
+
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans->data.F64[i] = psRandomUniform(myRNG);
+        //        printf("%f\n", rans->data.F64[i]);
+    }
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Mean is %f\n", stats->sampleMean);
+    stats->options = PS_STAT_SAMPLE_STDEV;
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Standard deviation is %f\n", stats->sampleStdev);
+    if ((fabs(stats->sampleMean - UNIFORM_MEAN) / UNIFORM_MEAN) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() mean is %f, should be %f\n", stats->sampleMean, UNIFORM_MEAN);
+        testStatus = false;
+    }
+    if ((fabs(stats->sampleStdev - UNIFORM_STDEV) / UNIFORM_STDEV) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() stdev is %f, should be %f\n", stats->sampleStdev, UNIFORM_STDEV);
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans);
+    psFree(stats);
+
+    psLogMsg(__func__,PS_LOG_INFO,"NULL psRandom variable, should generate error message");
+    if(psRandomUniform(NULL) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return zero for null psRandom");
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc() and psRandomUniform()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t02()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc() and psRandomGaussian()");
+
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans->data.F64[i] = psRandomGaussian(myRNG);
+        //        printf("%f\n", rans->data.F64[i]);
+    }
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Mean is %f\n", stats->sampleMean);
+    stats->options = PS_STAT_SAMPLE_STDEV;
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Standard deviation is %f\n", stats->sampleStdev);
+    if ((fabs(stats->sampleMean - GAUSSIAN_MEAN) / 1.0) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() mean is %f, should be %f\n", stats->sampleMean, GAUSSIAN_MEAN);
+        testStatus = false;
+    }
+    if ((fabs(stats->sampleStdev - GAUSSIAN_STDEV) / GAUSSIAN_STDEV) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() stdev is %f, should be %f\n", stats->sampleStdev, GAUSSIAN_STDEV);
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans);
+    psFree(stats);
+
+    psLogMsg(__func__,PS_LOG_INFO,"NULL psRandom variable, should generate error message");
+    if(psRandomGaussian(NULL) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return zero for null psRandom");
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc() and psRandomGaussian()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t03()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc() and psRandomPoisson()");
+
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans->data.F64[i] = psRandomPoisson(myRNG, POISSON_MEAN);
+        //        printf("%f\n", rans->data.F64[i]);
+    }
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Mean is %f\n", stats->sampleMean);
+    stats->options = PS_STAT_SAMPLE_STDEV;
+    stats = psVectorStats(stats, rans, NULL, NULL, 0);
+    printf("Standard deviation is %f\n", stats->sampleStdev);
+    if ((fabs(stats->sampleMean - POISSON_MEAN) / POISSON_MEAN) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() mean is %f, should be %f\n", stats->sampleMean, POISSON_MEAN);
+        testStatus = false;
+    }
+    if ((fabs(stats->sampleStdev - POISSON_STDEV) / POISSON_STDEV) > ERROR_TOLERANCE) {
+        printf("ERROR: psRandomUniform() stdev is %f, should be %f\n", stats->sampleStdev, POISSON_STDEV);
+        testStatus = false;
+    }
+
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans);
+    psFree(stats);
+
+    psLogMsg(__func__,PS_LOG_INFO,"NULL psRandom variable, should generate error message");
+    if(psRandomPoisson(NULL, POISSON_MEAN) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return zero for null psRandom");
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc() and psRandomPoisson()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t04()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans00 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans01 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans02 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc(), psRandomReset(), and psRandomUniform()");
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans00->data.F64[i] = psRandomUniform(myRNG);
+    }
+    psRandomReset(myRNG, SEED2);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans01->data.F64[i] = psRandomUniform(myRNG);
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans02->data.F64[i] = psRandomUniform(myRNG);
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        if (rans00->data.F64[i] != rans02->data.F64[i]) {
+            printf("ERROR: psRandomUniform() did not produce the same results with the same seed\n");
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans00);
+    psFree(rans01);
+    psFree(rans02);
+
+    psRandom *myRNG1 = NULL;
+    myRNG1 = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    psLogSetDestination("file:seed_msglog2.txt");
+    psRandomReset(myRNG1,0);
+    psLogSetDestination("dest:stderr");
+    psFree(myRNG1);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Reset a NULL psRandom variable, should generate an error message");
+    psRandomReset(NULL,SEED);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc(), psRandomReset(), and psRandomUniform()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t05()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans00 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans01 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans02 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc(), psRandomReset(), and psRandomGaussian()");
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans00->data.F64[i] = psRandomGaussian(myRNG);
+    }
+    psRandomReset(myRNG, SEED2);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans01->data.F64[i] = psRandomGaussian(myRNG);
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans02->data.F64[i] = psRandomGaussian(myRNG);
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        if (rans00->data.F64[i] != rans02->data.F64[i]) {
+            printf("ERROR: psRandomGaussian() did not produce the same results with the same seed\n");
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans00);
+    psFree(rans01);
+    psFree(rans02);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc(), psRandomReset(), and psRandomGaussian()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 t06()
+{
+    psRandom *myRNG = NULL;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    psVector *rans00 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans01 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    psVector *rans02 = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    printPositiveTestHeader(stdout,
+                            "psRandom functions",
+                            "psRandomAlloc(), psRandomReset(), and psRandomPoisson()");
+    myRNG = psRandomAlloc(PS_RANDOM_TAUS, SEED);
+    if (myRNG == NULL) {
+        printf("ERROR: Could not allocate psRandom structure\n");
+        testStatus = false;
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans00->data.F64[i] = psRandomPoisson(myRNG, POISSON_MEAN);
+    }
+    psRandomReset(myRNG, SEED2);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans01->data.F64[i] = psRandomPoisson(myRNG, POISSON_MEAN);
+    }
+    psRandomReset(myRNG, SEED);
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        rans02->data.F64[i] = psRandomPoisson(myRNG, POISSON_MEAN);
+    }
+
+    for (psS32 i = 0 ; i < NUM_DATA ; i++) {
+        if (rans00->data.F64[i] != rans02->data.F64[i]) {
+            printf("ERROR: psRandomPoisson() did not produce the same results with the same seed\n");
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myRNG);
+    psFree(rans00);
+    psFree(rans01);
+    psFree(rans02);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psRandom functions",
+                "psRandomAlloc(), psRandomReset(), and psRandomPoisson()",
+                testStatus);
+
+    return(testStatus);
+}
+
+psS32 main()
+{
+    testStatus = true;
+
+    t00();
+    t01();
+    t02();
+    t03();
+    t04();
+    t05();
+    t06();
+
+    return(!testStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats00.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats00.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats00.c	(revision 3057)
@@ -0,0 +1,214 @@
+/*****************************************************************************
+    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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float mean          = 0.0;
+    float realMeanNoMask   = 0.0;
+    float realMeanWithMask = 0.0;
+    psS32 count           = 0;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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, NULL, 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, NULL, 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");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    if( psVectorStats(myStats, NULL, NULL, NULL, 0) != myStats ) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorStats did not return stats when input NULL");
+        return 10;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    psStats *myStats2 = psVectorStats(NULL, myVector, NULL, NULL, 0);
+    if ( myStats2 != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorStats did not return NULL");
+        return 20;
+    }
+    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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psFree(myStats2);
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats01.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats01.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats01.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float max           = 0.0;
+    float realMaxNoMask   = 0.0;
+    float realMaxWithMask = 0.0;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats02.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats02.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats02.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float min           = 1e99;
+    float realMinNoMask   = 1e99;
+    float realMinWithMask = 1e99;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats03.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats03.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats03.c	(revision 3057)
@@ -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)
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float median        = 1e99;
+    float realMedianWithMask = (float) (N-3)/4;
+    float realMedianNoMask = (float) (N-1)/2;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats04.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats04.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats04.c	(revision 3057)
@@ -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)
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 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/rel4/psLib/test/dataManip/tst_psStats05.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats05.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats05.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 currentId       = psMemGetId();
+    psS32 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,false);
+    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/rel4/psLib/test/dataManip/tst_psStats06.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats06.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats06.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 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;
+    psS32 count           = 0;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats07.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats07.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats07.c	(revision 3057)
@@ -0,0 +1,495 @@
+/*****************************************************************************
+   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 90
+#define MEAN 32.0
+#define STDEV 2.0
+#define ERROR_TOLERANCE 0.15
+
+psS32 t00()
+{
+    psStats * myStats = NULL;
+    psS32 testStatus = true;
+    psS32 globalTestStatus = true;
+    psS32 i = 0;
+    psVector *myVector = NULL;
+    psVector *maskVector = NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // They must be changed if we adjust the number of data points.
+    // We don't really know that they are correct.
+    psS32 count = 0;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    float realMeanNoMask = MEAN;
+    float realMedianNoMask = MEAN;
+    float realModeNoMask = MEAN;
+    float realStdevNoMask = STDEV * 0.20;
+    float realLQNoMask = MEAN - ( 0.6 * STDEV );
+    float realUQNoMask = MEAN + ( 0.6 * STDEV );
+    psS32 realN50NoMask = N / 4;
+    psS32 realNfitNoMask = N / 4;
+
+    psTraceSetLevel(".psLib.dataManip", 0);
+    psTraceSetLevel(".psLib.dataManip.psMinimize", 0);
+    psTraceSetLevel(".psLib.dataManip.psMinimizeLMChi2Gauss1D", 0);
+    psTraceSetLevel(".psLib.dataManip.psFunctions.psGaussian", 0);
+    psTraceSetLevel(".psLib.dataManip.psFunctions", 0);
+
+    /*************************************************************************/
+    /*  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 = p_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, 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(testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "psStats(): deallocating memory" );
+
+    psFree( myStats );
+    psFree( myVector );
+    psFree( maskVector );
+
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psVector functions",
+                 "psStats(): deallocating memory",
+                 testStatus );
+
+    return ( !globalTestStatus );
+}
+
+
+psS32 t01()
+{
+    psStats * myStats = NULL;
+    psS32 testStatus = true;
+    psS32 globalTestStatus = true;
+    psS32 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.
+    psS32 count = 0;
+    psS32 currentId = psMemGetId();
+    psS32 memLeaks = 0;
+    float realMeanWithMask = MEAN;
+    float realMedianWithMask = MEAN;
+    float realModeWithMask = MEAN;
+    float realStdevWithMask = STDEV * 0.15;
+    float realLQWithMask = MEAN;
+    float realUQWithMask = MEAN;
+    psS32 realN50WithMask = N / 4;
+    psS32 realNfitWithMask = N / 4;
+
+    psTraceSetLevel(".psLib.dataManip.psStats", 10);
+
+    /*************************************************************************/
+    /*  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 = p_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 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, NULL, 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,false);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psVector functions",
+                 "psStats(): deallocating memory",
+                 testStatus );
+
+    return ( !globalTestStatus );
+}
+
+psS32 main()
+{
+    t00();
+    t01();
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats08.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats08.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats08.c	(revision 3057)
@@ -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)
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 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);
+    psS32 count           = 0;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, 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, NULL, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psStats09.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psStats09.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psStats09.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats *myStats    = NULL;
+    psS32 testStatus      = true;
+    psS32 globalTestStatus = true;
+    psS32 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;
+    psS32 count           = 0;
+    psS32 currentId       = psMemGetId();
+    psS32 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, 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, NULL, 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel4/psLib/test/dataManip/tst_psVectorFFT.c
===================================================================
--- /branches/rel4/psLib/test/dataManip/tst_psVectorFFT.c	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/tst_psVectorFFT.c	(revision 3057)
@@ -0,0 +1,643 @@
+/** @file  tst_psVectorFFT.c
+*
+*  @brief Contains the tests for psFFT.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 21:25:44 $
+*
+*  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 (psU32 row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (psU32 col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static psS32 testVectorFFT( void );
+static psS32 testVectorRealImaginary( void );
+static psS32 testVectorComplex( void );
+static psS32 testVectorConjugate( void );
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psFFT", tests, argc, argv ) );
+}
+
+psS32 testVectorFFT( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+    psVector* vec4 = 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 ( psU32 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(PS_ERR_UNKNOWN,true, "FFT didn't produce complex values?" );
+        return 1;
+    }
+
+    // 2a. verify output vector is same size as input
+    if ( vec2->n != vec->n ) {
+        psError(PS_ERR_UNKNOWN,true, "FFT didn't return vector with same size as input");
+        return 10;
+    }
+
+
+    // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    for ( psU32 n = 0; n < 100; n++ ) {
+        if ( n == 1 || n == 99 ) {
+            if ( fabsf( cabsf( vec2->data.C32[ n ] ) - 50.0f ) > 0.1f ) {
+                psError(PS_ERR_UNKNOWN,true, "FFT didn't work for vector (n=%d)", n );
+                return 2;
+            }
+        } else {
+            if ( fabsf( cabsf( vec2->data.C32[ n ] ) ) > 0.1f ) {
+                psError(PS_ERR_UNKNOWN,true, "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(PS_ERR_UNKNOWN,true, "FFT didn't produce complex values?" );
+        return 4;
+    }
+    if ( vec3->n != vec2->n ) {
+        psError(PS_ERR_UNKNOWN,true, "FFT didn't return vector with same size as input");
+        return 40;
+    }
+    for ( psU32 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(PS_ERR_UNKNOWN,true, "Reverse FFT didn't give me the original vector back (n=%d) (%.2f vs %.2f)",
+                    n, vecVal, val );
+            return 5;
+        }
+    }
+
+    // Perform a reverse transform with real flag set
+    vec4 = psVectorFFT(NULL,vec2, (PS_FFT_REVERSE | PS_FFT_REAL_RESULT));
+    if(vec4->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"FFT with real result did not produce real values");
+        return 80;
+    }
+
+    // Perform vector FFT with invalid direction flags
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    if ( psVectorFFT(NULL,vec2,(psFFTFlags)0) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with invalid direction");
+        return 70;
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+    psFree( vec4 );
+
+    // Perform vector FFT with null input
+    if ( psVectorFFT(NULL,NULL,PS_FFT_FORWARD) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 64;
+    }
+
+    return 0;
+}
+
+psS32 testVectorRealImaginary( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+    psVector* vec4 = NULL;
+    psVector* vec5 = NULL;
+    psVector* vec6 = NULL;
+    psVector* vec7 = NULL;
+    psVector* vec8 = NULL;
+    psVector* vec9 = NULL;
+    psVector* vec10 = NULL;
+    psVector* vec11 = 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 );
+    vec8 = psVectorAlloc( 100, PS_TYPE_C64 );
+    vec10 = psVectorAlloc( 100, PS_TYPE_C64 );
+    vec->n = vec->nalloc;
+    vec8->n = vec8->nalloc;
+    vec10->n = vec10->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec->data.C32[ n ] = n + I * ( n * 2 );
+        vec8->data.C64[n] = n + I * ( n * 2 );
+        vec10->data.C64[n] = n + I * ( n * 2 );
+    }
+    vec4 = psVectorAlloc( 100, PS_TYPE_F32);
+    vec4->n = vec4->nalloc;
+    vec6 = psVectorAlloc( 100, PS_TYPE_F32);
+    vec6->n = vec6->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec4->data.F32[n] = n;
+        vec6->data.F32[n] = n;
+    }
+
+    // 2. call psVectorReal and psVectorImaginary
+    vec2 = psVectorReal( vec2, vec );
+    if ( vec2 == NULL ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorReal returned a NULL?" );
+        return 1;
+    }
+    if ( vec2->type.type != PS_TYPE_F32 ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorReal returned a wrong type (%d)?",
+                vec2->type.type );
+        return 2;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate a warning.");
+    vec5 = psVectorReal(vec5, vec4);
+    if (vec5 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorReal returned NULL");
+        return 10;
+    }
+    if ( vec5->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorReal returned the wrong type");
+        return 11;
+    }
+
+    vec9 = psVectorReal(vec9,vec8);
+    if(vec9 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorReal returned NULL");
+        return 20;
+    }
+    if(vec9->type.type != PS_TYPE_F64) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorReal returned the wrong type");
+        return 21;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate a warning.");
+    vec3 = psVectorImaginary( vec3, vec );
+    if ( vec3 == NULL ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorImaginary returned a NULL?" );
+        return 3;
+    }
+    if ( vec3->type.type != PS_TYPE_F32 ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorImaginary returned a wrong type (%d)?",
+                vec3->type.type );
+        return 4;
+    }
+
+    vec7 = psVectorImaginary(vec7, vec6);
+    if(vec7 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorImage returned NULL");
+        return 12;
+    }
+    if(vec7->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorImaginary returned the wrong type");
+        return 13;
+    }
+
+    vec11 = psVectorImaginary(vec11, vec10);
+    if(vec11 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorImaginary returned NULL");
+        return 14;
+    }
+    if(vec11->type.type != PS_TYPE_F64) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorImaginary returned the wrong type");
+        return 15;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for ( psU32 n = 0; n < 100; n++ ) {
+        psF32 r = n;
+        psF32 i = ( n * 2 );
+        psF64 rr = n;
+        psF64 ii = ( n * 2 );
+        if ( fabsf( vec2->data.F32[ n ] - r ) > FLT_EPSILON ) {
+            psError(PS_ERR_UNKNOWN,true, "psVectorReal didn't return the real portion at n=%d",
+                    n );
+            return 5;
+        }
+        if ( fabsf( vec3->data.F32[ n ] - i ) > FLT_EPSILON ) {
+            psError(PS_ERR_UNKNOWN,true, "psVectorImaginary didn't return the real portion at n=%d",
+                    n );
+            return 6;
+        }
+        if ( fabsf( vec5->data.F32[n] - r) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorReal didn't return the real portion at n=%d",n);
+            return 50;
+        }
+        if ( fabsf( vec7->data.F32[n] - 0) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorImaginary did not return the imaginary portion at n=%d",n);
+            return 51;
+        }
+        if ( fabsf(vec9->data.F64[n] - rr) > FLT_EPSILON ) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorReal did not return the real portion at n=%d",n);
+            return 52;
+        }
+        if ( fabsf(vec11->data.F64[n] - ii) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorImaginary did not return the imaginary portion at n=%d",n);
+            return 53;
+        }
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+    psFree( vec4 );
+    psFree( vec5 );
+    psFree( vec6 );
+    psFree( vec7 );
+    psFree( vec8 );
+    psFree( vec9 );
+    psFree( vec10 );
+    psFree( vec11 );
+
+    // Perform vector Real with null input
+    if ( psVectorReal(NULL,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 63;
+    }
+    // Perform vector Imaginary with null input
+    if ( psVectorImaginary(NULL,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 73;
+    }
+
+    return 0;
+}
+
+psS32 testVectorComplex( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+    psVector* vec4 = NULL;
+    psVector* vec5 = NULL;
+    psVector* vec6 = 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 );
+    vec4 = psVectorAlloc( 100, PS_TYPE_F64 );
+    vec5 = psVectorAlloc( 100, PS_TYPE_F64 );
+    vec->n = vec->nalloc;
+    vec2->n = vec2->nalloc;
+    vec4->n = vec4->nalloc;
+    vec5->n = vec5->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec->data.F32[ n ] = n;
+        vec2->data.F32[ n ] = ( n * 2 );
+        vec4->data.F64[ n ] = n;
+        vec5->data.F64[ 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(PS_ERR_UNKNOWN,true, "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 ( psU32 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(PS_ERR_UNKNOWN,true, "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(PS_ERR_UNKNOWN,true, "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(PS_ERR_UNKNOWN,true, "psVectorComplex returned a larger vector than the input supported (%d).", vec3->n );
+        return 4;
+    }
+
+    // Verify the function works with psF64 type
+    vec6 = psVectorComplex(vec6, vec4, vec5);
+    if( vec6->type.type != PS_TYPE_C64 ) {
+        psError(PS_ERR_UNKNOWN,true,"Vector return type is not complex");
+        return 40;
+    }
+
+    // Verify error message generated with input of invalid type
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    vec4->type.type = PS_TYPE_S8;
+    vec5->type.type = PS_TYPE_S8;
+    vec6 = psVectorComplex(vec6, vec4, vec5);
+    if(vec6 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL for invalid type");
+        return 50;
+    }
+    vec4->type.type = PS_TYPE_F64;
+    vec5->type.type = PS_TYPE_F64;
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+    psFree( vec4 );
+    psFree( vec5 );
+
+    // Perform vector complex with null input
+    if ( psVectorComplex(NULL,NULL,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 62;
+    }
+
+    return 0;
+}
+
+psS32 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 ( psU32 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(PS_ERR_UNKNOWN,true, "the psVectorConjugate didn't return a C32 vector" );
+        return 1;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for ( psU32 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(PS_ERR_UNKNOWN,true, "psVectorConjugate result is invalid (n=%d, %.2f+%.2fi)",
+                    n, crealf( vec2->data.C32[ n ] ), cimagf( vec2->data.C32[ n ] ) );
+            return 2;
+        };
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+
+    // Perform conjugate for non-complex number
+    vec = psVectorAlloc( 100, PS_TYPE_F32 );
+    vec->n = vec->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec->data.F32[ n ] = n;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate a warning message.");
+    vec2 = psVectorConjugate(vec2,vec);
+    if(vec2->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorConjugate did not return a F32 vector");
+        return 10;
+    }
+    for ( psU32 n = 0; n < 100; n++ ) {
+        if( vec->data.F32[n] != vec2->data.F32[n] ) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorConjugate result is invalid (n=%d)",n);
+            return 11;
+        }
+    }
+    psFree(vec);
+
+    // Perform vector conjugate with C64 type
+    vec = psVectorAlloc( 100, PS_TYPE_C64 );
+    vec->n = vec->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec->data.C64[n] = n + I * ( n * 2 );
+    }
+    vec2 = psVectorConjugate(vec2,vec);
+    if(vec2->type.type != PS_TYPE_C64) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorConjugate did not return a C64 vector");
+        return 12;
+    }
+    for ( psU32 n = 0; n < 100; n++ ) {
+        if ( fabsf( crealf(vec->data.C64[n]) - crealf(vec2->data.C64[n])) > FLT_EPSILON ||
+                fabsf( cimagf(vec->data.C64[n]) - cimagf(vec2->data.C64[n])) > FLT_EPSILON ) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorConjugate result is invalid (n=%d)",n);
+            return 13;
+        }
+    }
+    psFree(vec);
+
+    // Perform vector conjugate with null input
+    if ( psVectorConjugate(NULL,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 61;
+    }
+
+    return 0;
+}
+
+psS32 testVectorPowerSpectrum( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+    psVector* vec4 = NULL;
+
+    psF32 val;
+    psF64 val1;
+
+    /*
+    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;
+    vec3 = psVectorAlloc(100,PS_TYPE_C64);
+    vec3->n = vec3->nalloc;
+    for ( psU32 n = 0; n < 100; n++ ) {
+        vec->data.C32[ n ] = n + I * sinf( ( ( psF32 ) n ) / 50.f * M_PI );
+        vec3->data.C64[ n ] = n + I * sinf( ( ( psF64 ) n ) / 50.f * M_PI );
+    }
+
+    // 2. call psVectorPowerSpectrum
+    vec2 = psVectorPowerSpectrum( vec2, vec );
+    vec4 = psVectorPowerSpectrum( vec4, vec3 );
+
+    // 3. verify result is psF32
+    if ( vec2->type.type != PS_TYPE_F32 ) {
+        psError(PS_ERR_UNKNOWN,true, "the type was not PS_TYPE_F32." );
+        return 1;
+    }
+    if ( vec4->type.type != PS_TYPE_F64 ) {
+        psError(PS_ERR_UNKNOWN,true,"psPowerSpectrum did not return type PS_TYPE_F64 type = %d",vec4->type.type);
+        return 20;
+    }
+
+    // 3a. verify result is the same size a input
+    // Awaiting IfA direction on bug #228
+    //    if ( vec2->n != vec->n ) {
+    //       psError(PS_ERR_UNKNOWN,true, "Output vector size different(%d) than input vector(%d)",vec2->n, vec->n);
+    //       return 10;
+    //    }
+
+    // 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;
+    val1= cabsf( vec3->data.C64[0] ) * cabsf(vec3->data.C64[0])/100/100;
+    if ( fabsf( vec2->data.F32[ 0 ] - val ) > FLT_EPSILON ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorPowerSpectrum result is invalid (n=0, %.2f %.2f)",
+                vec2->data.F32[ 0 ], val );
+        return 2;
+    }
+    if ( fabsf( vec4->data.C64[0] - val1 ) > FLT_EPSILON ) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorPowerSpectrum result is invalid (n=0)");
+        return 21;
+    }
+
+    for ( psU32 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;
+        val1 = (cabsf(vec3->data.C64[n]) * cabsf(vec3->data.C64[n]) +
+                cabsf(vec3->data.C64[100-n]) * cabsf(vec3->data.C64[100-n]))/100/100;
+        if ( fabsf( val - vec2->data.F32[ n ] ) > 10*FLT_EPSILON ) {
+            psError(PS_ERR_UNKNOWN,true, "psVectorPowerSpectrum result is invalid (n=%d, %.2f %.2f)",
+                    n, vec2->data.F32[ n ], val );
+            return 2;
+        }
+        if (fabsf(val1 - vec4->data.F64[n]) > 10*FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN,true,"psVectorPowerSpectrum result is invalid (n=%d, %.2f %.2f)",n,vec4->data.F64[n],val1);
+            return 22;
+        }
+    }
+
+    val = cabsf( vec->data.C32[ 50 ] ) * cabsf( vec->data.C32[ 50 ] ) / 100 / 100;
+    if ( fabsf( vec2->data.F32[ 50 ] - val ) > 10*FLT_EPSILON ) {
+        psError(PS_ERR_UNKNOWN,true, "psVectorPowerSpectrum result is invalid (n=50, %.2f %.2f)",
+                vec2->data.F32[ 0 ], val );
+        return 2;
+    };
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+    psFree( vec4 );
+
+    // Perform vector power spectrum with non-complex number
+    vec = psVectorAlloc(100,PS_TYPE_F32);
+    vec->n = vec->nalloc;
+    for( psU32 n=0; n<100; n++) {
+        vec->data.F32[n] = n;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    if(psVectorPowerSpectrum(NULL,vec) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psVectorPowerSpectrum did not return a null vector.");
+        return 10;
+    }
+
+    // Perform vector power spectrum with null input
+    if ( psVectorPowerSpectrum(NULL,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with null input vector");
+        return 60;
+    }
+
+    psFree(vec);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psFunc00.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psFunc00.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psFunc00.stderr	(revision 3057)
@@ -0,0 +1,2 @@
+Value using mask: 0.500000
+Value using coefficient zeroing: 0.500000
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psFunc01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 3057)
@@ -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{p_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{p_psGaussianDev()} | tst_psFunc01.c)
+
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stderr	(revision 3057)
@@ -0,0 +1,20 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psSpline1DAlloc (psFunctions.c:<LINENO>)
+    Error: max and min are equal.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psSpline1DAlloc (psFunctions.c:<LINENO>)
+    Error: max and min are equal.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psSpline1DAllocGeneric (psFunctions.c:<LINENO>)
+    Error: order is less than 0.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psSpline1DAllocGeneric (psFunctions.c:<LINENO>)
+    Unallowable operation: psVector bounds or its data is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psSpline1DAllocGeneric (psFunctions.c:<LINENO>)
+    Unallowable operation: psVector bounds has no elements.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psFunc02.stdout	(revision 3057)
@@ -0,0 +1,115 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(): linear, normal}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psSpline1D->domains[0] is 1.000000
+psSpline1D->domains[1] is 3.250000
+psSpline1D->domains[2] is 5.500000
+psSpline1D->domains[3] is 7.750000
+psSpline1D->domains[4] is 10.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): linear, normal} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(): linear, min/max are equal} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): linear, min/max are equal} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(): linear, min > max.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psSpline1D->domains[0] is 1.000000
+psSpline1D->domains[1] is 0.500000
+psSpline1D->domains[2] is 0.000000
+psSpline1D->domains[3] is -0.500000
+psSpline1D->domains[4] is -1.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): linear, min > max.} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(), cubic, normal}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psSpline1D->domains[0] is 1.000000
+psSpline1D->domains[1] is 3.250000
+psSpline1D->domains[2] is 5.500000
+psSpline1D->domains[3] is 7.750000
+psSpline1D->domains[4] is 10.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): cubic, normal} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(): cubic, min/max are equal} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): cubic, min/max are equal} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAlloc(): cubic, min > max.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psSpline1D->domains[0] is 1.000000
+psSpline1D->domains[1] is 0.500000
+psSpline1D->domains[2] is 0.000000
+psSpline1D->domains[3] is -0.500000
+psSpline1D->domains[4] is -1.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAlloc(): cubic, min > max.} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAllocGeneric(): linear, normal} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psSpline1D->domains[0] is 2.000000
+psSpline1D->domains[1] is 4.000000
+psSpline1D->domains[2] is 6.000000
+psSpline1D->domains[3] is 8.000000
+psSpline1D->domains[4] is 10.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAllocGeneric(): linear, normal} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAllocGeneric(): negative order} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAllocGeneric(): negative order} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAllocGeneric(): bound equal to NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAllocGeneric(): bound equal to NULL} | tst_psFunc02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc02.c                                             *
+*            TestPoint: psFunction functions{psSpline1DAllocGeneric(): bounds with zero elements} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFunctions functions{psSpline1DAllocGeneric(): bounds with zero elements} | tst_psFunc02.c)
+
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psHistogramAlloc (psStats.c:<LINENO>)
+    Error: (lower > upper) (30.000000 20.000000)
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psHist01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psHist02.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psHist02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psHist02.stderr	(revision 3057)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorHistogram (psStats.c:<LINENO>)
+    Unallowable operation: out is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorHistogram (psStats.c:<LINENO>)
+    Unallowable operation: psVector in or its data is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psHist02.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 3057)
@@ -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.000000)
+
+---> 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.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (25.00 - 30.00) data (5000.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (25.000 - 30.000) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (21.00 - 22.00) data (1000.000000)
+Bin number 2 bounds: (22.00 - 23.00) data (1000.000000)
+Bin number 3 bounds: (23.00 - 24.00) data (1000.000000)
+Bin number 4 bounds: (24.00 - 25.00) data (1000.000000)
+Bin number 5 bounds: (25.00 - 26.00) data (1000.000000)
+Bin number 6 bounds: (26.00 - 27.00) data (1000.000000)
+Bin number 7 bounds: (27.00 - 28.00) data (1000.000000)
+Bin number 8 bounds: (28.00 - 29.00) data (1000.000000)
+Bin number 9 bounds: (29.00 - 30.00) data (1000.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (21.000 - 22.000) data (1000.000000)
+Bin number 2 bounds: (22.000 - 23.000) data (1000.000000)
+Bin number 3 bounds: (23.000 - 24.000) data (1000.000000)
+Bin number 4 bounds: (24.000 - 25.000) data (1000.000000)
+Bin number 5 bounds: (25.000 - 26.000) data (0.000000)
+Bin number 6 bounds: (26.000 - 27.000) data (0.000000)
+Bin number 7 bounds: (27.000 - 28.000) data (0.000000)
+Bin number 8 bounds: (28.000 - 29.000) data (0.000000)
+Bin number 9 bounds: (29.000 - 30.000) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (20.50 - 21.00) data (500.000000)
+Bin number 2 bounds: (21.00 - 21.50) data (500.000000)
+Bin number 3 bounds: (21.50 - 22.00) data (500.000000)
+Bin number 4 bounds: (22.00 - 22.50) data (500.000000)
+Bin number 5 bounds: (22.50 - 23.00) data (500.000000)
+Bin number 6 bounds: (23.00 - 23.50) data (500.000000)
+Bin number 7 bounds: (23.50 - 24.00) data (500.000000)
+Bin number 8 bounds: (24.00 - 24.50) data (500.000000)
+Bin number 9 bounds: (24.50 - 25.00) data (500.000000)
+Bin number 10 bounds: (25.00 - 25.50) data (500.000000)
+Bin number 11 bounds: (25.50 - 26.00) data (500.000000)
+Bin number 12 bounds: (26.00 - 26.50) data (500.000000)
+Bin number 13 bounds: (26.50 - 27.00) data (500.000000)
+Bin number 14 bounds: (27.00 - 27.50) data (500.000000)
+Bin number 15 bounds: (27.50 - 28.00) data (500.000000)
+Bin number 16 bounds: (28.00 - 28.50) data (500.000000)
+Bin number 17 bounds: (28.50 - 29.00) data (500.000000)
+Bin number 18 bounds: (29.00 - 29.50) data (500.000000)
+Bin number 19 bounds: (29.50 - 30.00) data (500.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (20.500 - 21.000) data (500.000000)
+Bin number 2 bounds: (21.000 - 21.500) data (500.000000)
+Bin number 3 bounds: (21.500 - 22.000) data (500.000000)
+Bin number 4 bounds: (22.000 - 22.500) data (500.000000)
+Bin number 5 bounds: (22.500 - 23.000) data (500.000000)
+Bin number 6 bounds: (23.000 - 23.500) data (500.000000)
+Bin number 7 bounds: (23.500 - 24.000) data (500.000000)
+Bin number 8 bounds: (24.000 - 24.500) data (500.000000)
+Bin number 9 bounds: (24.500 - 25.000) data (500.000000)
+Bin number 10 bounds: (25.000 - 25.500) data (0.000000)
+Bin number 11 bounds: (25.500 - 26.000) data (0.000000)
+Bin number 12 bounds: (26.000 - 26.500) data (0.000000)
+Bin number 13 bounds: (26.500 - 27.000) data (0.000000)
+Bin number 14 bounds: (27.000 - 27.500) data (0.000000)
+Bin number 15 bounds: (27.500 - 28.000) data (0.000000)
+Bin number 16 bounds: (28.000 - 28.500) data (0.000000)
+Bin number 17 bounds: (28.500 - 29.000) data (0.000000)
+Bin number 18 bounds: (29.000 - 29.500) data (0.000000)
+Bin number 19 bounds: (29.500 - 30.000) data (0.000000)
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrix01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 3057)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Transpose input image into output image} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Transpose input image into auto allocated NULL output image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Transpose 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/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 3057)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMatrixTranspose (psMatrix.c:<LINENO>)
+    Invalid operation: Pointer to inImage is same as outImage.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose (psMatrix.c:<LINENO>)
+    Unallowable operation: psImage inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose (psMatrix.c:<LINENO>)
+    Invalid operation. inImage not PS_TYPE_F64.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 3057)
@@ -0,0 +1,55 @@
+/***************************** 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{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/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 3057)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMatrixLUD (psMatrix.c:<LINENO>)
+    Unallowable operation: psImage inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixLUSolve (psMatrix.c:<LINENO>)
+    Unallowable operation: psVector inVector or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixLUSolve (psMatrix.c:<LINENO>)
+    Unallowable operation: psImage inImage or its data is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 3057)
@@ -0,0 +1,69 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Calculate LU matrix} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Determine solution to matrix equation}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|E|psMatrixInvert (psMatrix.c:<LINENO>)
+    Unallowable operation: psImage inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixInvert (psMatrix.c:<LINENO>)
+    Unallowable operation: det is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 3057)
@@ -0,0 +1,58 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Invert matrix and calculate determinant} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Calculate determinant only}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrix05.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 3057)
@@ -0,0 +1,27 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Multiply images}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrix06.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 3057)
@@ -0,0 +1,27 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Calculate Eigenvectors}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 3057)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMatrixToVector (psMatrix.c:<LINENO>)
+    Unallowable operation: psImage inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixToVector (psMatrix.c:<LINENO>)
+    Image does not have dim with 1 col or 1 row: (2 x 2).
+<DATE><TIME>|<HOST>|E|psVectorToMatrix (psMatrix.c:<LINENO>)
+    Unallowable operation: psVector inVector or its data is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 3057)
@@ -0,0 +1,87 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr	(revision 3057)
@@ -0,0 +1,66 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: input1 is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: input2 is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: op is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psUnaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: in is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psUnaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: op is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    ptr input1 has type 1028, ptr input2 has type 1032.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Specified psImage dimensions differed, 2x2 vs 3x3.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Number of elements inconsistent, 2 vs 3.  Number of elements must match.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Number of elements inconsistent, 2 vs 3.  Number of elements must match.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an two error messages
+<DATE><TIME>|<HOST>|E|psVectorRecycle (psVector.c:<LINENO>)
+    The input psVector must have a vector dimension type.
+<DATE><TIME>|<HOST>|E|psUnaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Couldn't create a proper output psVector.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    The minimum operation is not supported with complex data.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    The maximum operation is not supported with complex data.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error messgae
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Specified operation, yarg, is not supported.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psUnaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Specified operation, yarg, is not supported.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psBinaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Unallowable operation: input1 has incorrect dimensionality.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psUnaryOp (psMatrixVectorArithmetic.c:<LINENO>)
+    Specified parameter, in, has invalid dimensionality, 4.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout	(revision 3057)
@@ -0,0 +1,180 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check for output generated}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check for output generated} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check for null input arg 1}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check for null input arg 1} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check for null input arg 2}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check for null input arg 2} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check for null operand}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check for null operand} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check for null output}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check for null output} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check for null input}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check for null input} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check for null operator}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check for null operator} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Inconsistent element types}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Inconsistent element types} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check output type conversion}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check output type conversion} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check for inconsistent elements}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check for inconsistent elements} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check inconsistent elements in input and output} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check inconsistent elements in input and output} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check inconsistent size}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check inconsistent size} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Check inconsistent size}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Check inconsistent size} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Check inconsistent dimensionality}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Check inconsistent dimensionality} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Attempt to use min with complex numbers}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Attempt to use  min with complex numbers} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Attempt to use max with complex numbers}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Attempt to use max with complex numbers} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinary{Attempt to use invalid operator}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Attempt to use invalid operator} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Attempt to use invalid operator}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Attempt to use invalid operator} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psBinaryOp{Attempt to use input with PS_DIMEN_OTHER}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{Attempt to use input with PS_DIMEN_OTHER} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psUnaryOp{Attempt to use input with PS_DIMEN_OTHER}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{Attempt to use input with PS_DIMEN_OTHER} | tst_psMatrixVectorArithmetic03.c)
+
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic04.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic04.stderr	(revision 3057)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic04.c                           *
+*            TestPoint: psBinaryOp{psBinaryOp}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{psBinaryOp} | tst_psMatrixVectorArithmetic04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic04.c                           *
+*            TestPoint: psBinaryOp{psBinaryOp}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{psBinaryOp} | tst_psMatrixVectorArithmetic04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic04.c                           *
+*            TestPoint: psBinaryOp{psBinaryOp}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psBinaryOp{psBinaryOp} | tst_psMatrixVectorArithmetic04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic04.c                           *
+*            TestPoint: psUnaryOp{psUnaryOp}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psUnaryOp{psUnaryOp} | tst_psMatrixVectorArithmetic04.c)
+
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate an error for null input polynomial.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D (psMinimize.c:<LINENO>)
+    Unallowable operation: polynomial myPoly or its coeffs is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D (psMinimize.c:<LINENO>)
+    Unallowable operation: polynomial myPoly or its coeffs is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate an error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D (psMinimize.c:<LINENO>)
+    Unallowable operation: polynomial myPoly or its coeffs is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D (psMinimize.c:<LINENO>)
+    Unallowable operation: polynomial myPoly or its coeffs is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psMinimize05.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize05.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psMinimize05.stderr	(revision 3057)
@@ -0,0 +1,16 @@
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null minimize.
+<DATE><TIME>|<HOST>|E|psMinimizePowell (psMinimize.c:<LINENO>)
+    Unallowable operation: min is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null parameter vector
+<DATE><TIME>|<HOST>|E|psMinimizePowell (psMinimize.c:<LINENO>)
+    Unallowable operation: psVector params or its data is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null coords.
+<DATE><TIME>|<HOST>|E|psMinimizePowell (psMinimize.c:<LINENO>)
+    Unallowable operation: coords is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null function
+<DATE><TIME>|<HOST>|E|psMinimizePowell (psMinimize.c:<LINENO>)
+    Unallowable operation: func is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stderr	(revision 3057)
@@ -0,0 +1,20 @@
+<DATE><TIME>|<HOST>|I|t00
+    Invalid type, should generate error message
+<DATE><TIME>|<HOST>|E|psRandomAlloc (psRandom.c:<LINENO>)
+    Unknown Random Number Generator Type
+<DATE><TIME>|<HOST>|I|t01
+    NULL psRandom variable, should generate error message
+<DATE><TIME>|<HOST>|E|psRandomUniform (psRandom.c:<LINENO>)
+    Random variable is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    NULL psRandom variable, should generate error message
+<DATE><TIME>|<HOST>|E|psRandomGaussian (psRandom.c:<LINENO>)
+    Random variable is NULL.
+<DATE><TIME>|<HOST>|I|t03
+    NULL psRandom variable, should generate error message
+<DATE><TIME>|<HOST>|E|psRandomPoisson (psRandom.c:<LINENO>)
+    Random variable is NULL.
+<DATE><TIME>|<HOST>|I|t04
+    Reset a NULL psRandom variable, should generate an error message
+<DATE><TIME>|<HOST>|E|psRandomReset (psRandom.c:<LINENO>)
+    Random variable is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psRandom.stdout	(revision 3057)
@@ -0,0 +1,69 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc()}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc() and psRandomUniform()}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Mean is 0.498160
+Standard deviation is 0.287816
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc() and psRandomUniform()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc() and psRandomGaussian()} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Mean is -0.007538
+Standard deviation is 0.992094
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc() and psRandomGaussian()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc() and psRandomPoisson()}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Mean is 14.978700
+Standard deviation is 3.858498
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc() and psRandomPoisson()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomUniform()} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomUniform()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomGaussian()} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomGaussian()} | tst_psRandom.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psRandom.c                                             *
+*            TestPoint: psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomPoisson()} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psRandom functions{psRandomAlloc(), psRandomReset(), and psRandomPoisson()} | tst_psRandom.c)
+
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stderr	(revision 3057)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorStats (psStats.c:<LINENO>)
+    Unallowable operation: psVector in or its data is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorStats (psStats.c:<LINENO>)
+    Unallowable operation: stats is NULL.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats01.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats02.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats03.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats05.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats06.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats07.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats07.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats07.stderr	(revision 3057)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|W|p_psVectorRobustStats
+    WARNING: the fitted Gaussian has more than 10% error for the stdev.
+<DATE><TIME>|<HOST>|W|p_psVectorRobustStats
+    WARNING: Using the calculated stdev instead of Gaussian-fitted stdev.
Index: /branches/rel4/psLib/test/dataManip/verified/tst_psStats08.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 3057)
@@ -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/rel4/psLib/test/dataManip/verified/tst_psStats09.stdout
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 3057)
@@ -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.447365
+
+---> 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.288097
+
+---> 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/rel4/psLib/test/dataManip/verified/tst_psVectorFFT.stderr
===================================================================
--- /branches/rel4/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 3057)
@@ -0,0 +1,73 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorFFT}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testVectorFFT
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorFFT (psVectorFFT.c:<LINENO>)
+    Must specify the direction as either PS_FFT_FORWARD or PS_FFT_REVERSE.
+
+---> TESTPOINT PASSED (psFFT{psVectorFFT} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorRealImaginary}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testVectorRealImaginary
+    Following should generate a warning.
+<DATE><TIME>|<HOST>|W|psVectorReal
+    Real portion of a non-Complex type called called for. Just a vector copy was performed.
+<DATE><TIME>|<HOST>|I|testVectorRealImaginary
+    Following should generate a warning.
+<DATE><TIME>|<HOST>|W|psVectorImaginary
+    Imaginary portion of a non-Complex type called for. A zeroed vector was returned.
+
+---> 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|psVectorComplex (psVectorFFT.c:<LINENO>)
+    Real psVector type, psF32, and imaginary psVector type, psF64, must be the same.
+<DATE><TIME>|<HOST>|I|testVectorComplex
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorComplex (psVectorFFT.c:<LINENO>)
+    Input psVector type, psS8, is required to be either psF32 or psF64.
+
+---> TESTPOINT PASSED (psFFT{psVectorComplex} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorConjugate}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testVectorConjugate
+    Following should generate a warning message.
+<DATE><TIME>|<HOST>|W|psVectorConjugate
+    Complex Conjugate of a non-Complex type called for. Vector copy was performed instead.
+
+---> TESTPOINT PASSED (psFFT{psVectorConjugate} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorPowerSpectrum}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testVectorPowerSpectrum
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psVectorPowerSpectrum (psVectorFFT.c:<LINENO>)
+    Input psVector type, psF32, is required to be either psC32 or psC64.
+
+---> TESTPOINT PASSED (psFFT{psVectorPowerSpectrum} | tst_psVectorFFT.c)
+
Index: /branches/rel4/psLib/test/fileUtils/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/fileUtils/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/.cvsignore	(revision 3057)
@@ -0,0 +1,5 @@
+temp
+tst_psLookupTable_01
+tst_psFits
+multi.fits
+table.fits
Index: /branches/rel4/psLib/test/fileUtils/Makefile
===================================================================
--- /branches/rel4/psLib/test/fileUtils/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/Makefile	(revision 3057)
@@ -0,0 +1,43 @@
+################################################################################
+##
+##  Makefile:   test/fileUtils
+##
+##  $Revision: 1.2 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-12 22:17:02 $
+##
+##  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_psLookupTable_01 \
+	tst_psFits
+
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/fileUtils'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
Index: /branches/rel4/psLib/test/fileUtils/tst_psFits.c
===================================================================
--- /branches/rel4/psLib/test/fileUtils/tst_psFits.c	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/tst_psFits.c	(revision 3057)
@@ -0,0 +1,1135 @@
+/** @file  tst_psFits.c
+*
+*  @brief Contains the tests for psFits.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-18 19:35:24 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (psU32 row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (psU32 col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static bool makeMulti(void);  // implicitly tests psFitsSetExtName
+static bool makeTable(void);
+const char* multiFilename = "multi.fits";
+const char* tableFilename = "table.fits";
+const int tableNumRows = 10;
+
+
+// N.B., the tests to Image read/write was liberally taken from the now
+// deprecated psImageReadSection/psImageWriteSection function tests.
+static psS32 testImageRead(void);
+static psS32 testImageWrite(void);
+
+static psS32 tst_psFitsAlloc( void );
+static psS32 tst_psFitsMoveExtName( void ); // also tests psFitsGetExtName
+static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum, psFitsGetSize
+static psS32 tst_psFitsReadHeader( void );
+static psS32 tst_psFitsReadHeaderSet( void );
+static psS32 tst_psFitsReadTable( void );
+
+testDescription tests[] = {
+                              {tst_psFitsAlloc, 801, "psFitsAlloc", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsMoveExtName", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsGetExtName", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsMoveExtNum", 0, false},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetExtNum", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetSize", 0, true},
+                              {tst_psFitsReadHeader, 804, "psFitsReadHeader", 0, false},
+                              {tst_psFitsReadHeaderSet,805, "psFitsReadHeaderSet", 0, false},
+                              {tst_psFitsReadTable,809, "psFitsReadTable", 0, false},
+                              {testImageRead,567, "psFitsReadImage", 0, false},
+                              {testImageWrite,569, "psFitsWriteImage", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+bool makeMulti(void)
+{
+
+    remove
+        (multiFilename);
+
+    psFits* fitsFile = psFitsAlloc(multiFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not create 'multi' FITS file.");
+        return false;
+    }
+
+    psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+    char extname[80];
+    for (int lcv = 0; lcv < 8; lcv++) {
+        snprintf(extname,80,"ext-%d", lcv);
+
+        psMetadata* header = psMetadataAlloc();
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                      PS_TYPE_S32, PS_META_PRIMITIVE,
+                      "psS32 Item", (psS32)lcv);
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                      PS_TYPE_F32, PS_META_PRIMITIVE,
+                      "psF32 Item", (float)(1.0f/(float)(1+lcv)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                      PS_TYPE_F64, PS_META_PRIMITIVE,
+                      "psF64 Item", (double)(1.0/(double)(1+lcv)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                      PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                      "psBool Item",
+                      (lcv%2 == 0));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYSTR",
+                      PS_TYPE_PTR, PS_META_STR,
+                      "String Item",
+                      extname);
+
+        // set the pixels in the image
+        psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
+        if (! psFitsWriteImage(fitsFile,header,image,1, extname) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not write image.");
+            return false;
+        }
+
+        psFree(header);
+    }
+    psFree(image);
+    psFree(fitsFile);
+
+    return true;
+}
+
+bool makeTable(void)
+{
+
+    remove
+        (tableFilename);
+
+    psFits* fitsFile = psFitsAlloc(tableFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not create 'table' FITS file.");
+        return false;
+    }
+
+    // make the PHU an image (per FITS standard, it must be)
+    psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+    if (! psFitsWriteImage(fitsFile,NULL,image,1,"primary") ) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Could not write PHU image.");
+        return false;
+    }
+
+    psFree(image);
+
+    // build a table structure
+    psArray* table = psArrayAlloc(tableNumRows);
+    table->n = 0;
+    for (int row = 0; row < tableNumRows; row++) {
+        psMetadata* header = psMetadataAlloc();
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                      PS_TYPE_S32, PS_META_PRIMITIVE,
+                      "psS32 Item", (psS32)row);
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                      PS_TYPE_F32, PS_META_PRIMITIVE,
+                      "psF32 Item", (float)(1.0f/(float)(1+row)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                      PS_TYPE_F64, PS_META_PRIMITIVE,
+                      "psF64 Item", (double)(1.0/(double)(1+row)));
+
+        psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                      PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                      "psBool Item",
+                      (row%2 == 0));
+
+        psArrayAdd(table,0,header);
+    }
+
+    psFitsWriteTable(fitsFile, NULL, table, "table-1");
+
+    psFree(table);
+    psFree(fitsFile);
+
+    return true;
+}
+
+psS32 tst_psFitsAlloc( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fitsFile = psFitsAlloc(multiFilename);
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int extNum = psFitsGetExtNum(fitsFile);
+    if (extNum != 0) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc was not queued to the PHU, but to extension #%d.",
+                extNum);
+        return 2;
+    }
+
+    psFree(fitsFile);
+
+    // make sure the file doesn't already exist.
+    if (access("new.fits", F_OK) == 0) {
+        if (remove
+                ("new.fits") != 0) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Couldn't delete the new.fits file.");
+            return 3;
+        }
+    }
+
+    fitsFile = psFitsAlloc("new.fits");
+
+    if (fitsFile == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 4;
+    }
+
+    psFree(fitsFile);
+
+    // now, if psFitsAlloc actually created the file, I shouldn't error in removing it.
+    if (remove
+            ("new.fits") != 0) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc seemed to not have created a new file.");
+        return 5;
+    }
+
+
+    return 0;
+}
+
+psS32 tst_psFitsMoveExtName( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 2) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extName[80];
+    psRegion region = {0,0,0,0};
+
+    for (int lcv = 0; lcv < numHDUs; lcv++) {
+        snprintf(extName,80,"ext-%d",lcv);
+        // try to move to the named extension.
+        if (! psFitsMoveExtName(fits, extName) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to ext-%d.",
+                    lcv);
+            return 3;
+        }
+
+        // check to see if I can retrieve the name back from the psFits object.
+        char* nameFromFile = psFitsGetExtName(fits);
+        if (strcmp(nameFromFile,extName) != 0) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension name back ('%s' vs '%s'",
+                    nameFromFile, extName);
+            return 3;
+        }
+        psFree(nameFromFile);
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 4;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-1; lcv >= 0; lcv--) {
+        snprintf(extName,80,"ext-%d",lcv);
+        // try to move to the named extension.
+        if (! psFitsMoveExtName(fits, extName) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to ext-%d.",
+                    lcv);
+            return 5;
+        }
+
+        // check to see if I can retrieve the name back from the psFits object.
+        char* nameFromFile = psFitsGetExtName(fits);
+        if (strcmp(nameFromFile,extName) != 0) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension name back ('%s' vs '%s'",
+                    nameFromFile, extName);
+            return 5;
+        }
+        psFree(nameFromFile);
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 6;
+        }
+        psFree(image);
+    }
+
+    // check to see if given a bogus extension name, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(fits, "bogus") || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to non-existant HDU didn't fail.");
+        return 7;
+    }
+
+    // check to see if given a NULL psFits, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(NULL, "bogus") || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL psFits didn't fail.");
+        return 8;
+    }
+
+    // check to see if given a NULL extname, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    if (psFitsMoveExtName(fits, NULL) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL extname didn't fail.");
+        return 9;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
+
+psS32 tst_psFitsMoveExtNum( void )
+{
+
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    // as a side test, let's make sure psFitsGetSize can handle NULL.
+    psLogMsg(__func__,PS_LOG_INFO,
+             "Following should be an error.");
+    psErrorClear();
+    if (psFitsGetSize(NULL) != 0 || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    if (numHDUs != 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    psRegion region = {0,0,0,0};
+
+    // test absolute positioning
+    for (int lcv = 0; lcv < numHDUs; lcv++) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, lcv, false) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 3;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 5;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 4;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-1; lcv >= 0; lcv--) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, lcv, false) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 5;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 6;
+        }
+        psFree(image);
+    }
+
+    // test relative positioning
+    psFitsMoveExtNum(fits,0,false);
+    for (int lcv = 1; lcv < numHDUs; lcv++) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, 1, true) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 13;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 13;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (image == NULL || abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 14;
+        }
+        psFree(image);
+    }
+
+    for (int lcv = numHDUs-2; lcv >= 0; lcv--) {
+        // try to move to the extension
+        if (! psFitsMoveExtNum(fits, -1, true) ) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to move to extension %d.",
+                    lcv);
+            return 15;
+        }
+
+        // check to see if I can retrieve the number back from the psFits object.
+        if (psFitsGetExtNum(fits) != lcv) { // hey, it didn't move?
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to retrieve the extension number back (%d vs %d)",
+                    psFitsGetExtNum(fits), lcv);
+            return 15;
+        }
+
+        // check that the image is associated to the extension moved, i.e.,
+        // did we really move to the proper extension?
+        psImage* image = psFitsReadImage(NULL, fits,region,0);
+
+        if (abs(image->data.F32[0][0] - (float)lcv) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "The image pixel 0,0 of ext-%d was %g, expected %d.",
+                    lcv,image->data.F32[0][0],lcv);
+            return 16;
+        }
+        psFree(image);
+    }
+
+    // check to see if given a negative extension number, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, -1, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 21;
+    }
+
+    // check to see if relative positioning beyond PHU, it errors.
+    psFitsMoveExtNum(fits,0,false);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, -1, true) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 22;
+    }
+
+
+    // check to see if given a extension greater than the total #HDUs, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, numHDUs, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to a HDU beyond the file's contents didn't fail.");
+        return 31;
+    }
+
+    // check to see if relative positioning beyond PHU, it errors.
+    psFitsMoveExtNum(fits,numHDUs-1,false);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(fits, 1, true) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Moving to negative HDU didn't fail.");
+        return 32;
+    }
+
+    // check to see if given a NULL psFits, it errors.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error.");
+    psErrorClear();
+    if (psFitsMoveExtNum(NULL, 0, false) || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Operation of NULL psFits didn't fail.");
+        return 40;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
+
+
+
+static psS32 tst_psFitsReadHeader( void )
+{
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extname[80];
+    for (int hdunum = 0; hdunum < numHDUs; hdunum++) {
+        snprintf(extname,80,"ext-%d",hdunum);
+
+        psFitsMoveExtNum(fits,hdunum,false);
+
+        psMetadata* header = psFitsReadHeader(NULL,fits);
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 3;
+        }
+
+        psMetadata* header2 = psMetadataAlloc();
+        header2 = psFitsReadHeader(header2,fits);
+        if (header2 == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 11;
+        }
+
+        if (header->list->size < 1 || header->list->size != header2->list->size) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Reading the header given a NULL input psMetadata differed "
+                    "from giving an existing psMetadata.");
+            return 12;
+        }
+
+        // check for the extra metadata items
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(header, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(header, "MYDBL",NULL);
+        psMetadataItem* boolItem = psMetadataLookup(header, "MYBOOL");
+        char* strItem = psMetadataLookupPtr(header, "MYSTR",NULL);
+
+        if (intItem != hdunum) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file.");
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+hdunum)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file.  Got %f vs %f",
+                    fltItem,1.0f/(float)(1+hdunum));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+hdunum)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file.  Got %g vs %g",
+                    dblItem, 1.0/(double)(1+hdunum));
+            return 22;
+        }
+
+        if (boolItem == NULL ||
+                boolItem->type != PS_META_PRIMITIVE ||
+                boolItem->pType != PS_TYPE_BOOL) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file.");
+            return 23;
+        }
+
+        if (strItem == NULL || strncmp(strItem,extname,strlen(extname)) != 0) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve string metadata item from file.  Got '%s' vs '%s' (%d)",
+                    strItem,extname,strlen(extname));
+            return 24;
+        }
+
+        psFree(header);
+        psFree(header2);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following should be an error (input psFits = NULL)");
+    psMetadata* header = psFitsReadHeader(NULL,NULL);
+
+    if (header != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadHeader didn't error on a NULL psFits.");
+        return 30;
+    }
+
+
+    psFree(fits);
+
+    return 0;
+}
+
+static psS32 tst_psFitsReadHeaderSet( void )
+{
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    // move to the middle
+    psFitsMoveExtNum(fits,numHDUs/2, false);
+
+    psHash* headerSet = psFitsReadHeaderSet(NULL, fits);
+
+    if (headerSet == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned NULL unexpectedly.");
+        return 3;
+    }
+
+    if (psFitsGetExtNum(fits) != numHDUs/2) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet changed the CHU.");
+        return 4;
+    }
+
+    char extname[80];
+    for (int i = 0; i < numHDUs; i++) {
+        if (i == 0) {
+            snprintf(extname, 80, "PHU");
+        } else {
+            snprintf(extname, 80, "ext-%d", i);
+        }
+
+        psMetadata* header = psHashLookup(headerSet, extname);
+
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader returned NULL unexpectedly for HDU#%d.",
+                    i);
+            return 5;
+        }
+
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+
+        if (intItem != i) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader for HDU#%d had a MYINT of %d, expected %d.",
+                    intItem, i);
+            return 6;
+        }
+
+    }
+
+    psHash* set2 = psHashAlloc(20);
+
+    if (psFitsReadHeaderSet(set2,NULL) != NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned non-NULL given a NULL psFits.");
+        return 10;
+    }
+
+    psHash* set3 = psHashAlloc(20);
+    psFitsReadHeaderSet(set3,fits);
+
+    if (set3 == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadHeaderSet returned NULL unexpectedly.");
+        return 11;
+    }
+
+    for (int i = 0; i < numHDUs; i++) {
+        if (i == 0) {
+            snprintf(extname, 80, "PHU");
+        } else {
+            snprintf(extname, 80, "ext-%d", i);
+        }
+
+        psMetadata* header = psHashLookup(set3, extname);
+
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader returned NULL unexpectedly for HDU#%d.",
+                    i);
+            return 5;
+        }
+
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+
+        if (intItem != i) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "psFitsReadHeader for HDU#%d had a MYINT of %d, expected %d.",
+                    intItem, i);
+            return 6;
+        }
+
+    }
+
+
+
+    psFree(headerSet);
+    psFree(set3);
+    // set2 should have been freed by psFitsReadHeaderSet upon an error.
+
+    psFree(fits);
+
+    return 0;
+}
+
+static psS32 tst_psFitsReadTable( void )
+{
+
+
+    if (! makeTable() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(tableFilename);
+
+    if (fits == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsAlloc returned NULL on existing file.");
+        return 1;
+    }
+
+    psFitsMoveExtNum(fits,1,false);
+
+    psArray* table = psFitsReadTable(fits);
+
+    if (table == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psFitsReadTable returned NULL unexpectedly.");
+        return 2;
+    }
+
+    if (table->n != tableNumRows) {
+        psError(PS_ERR_UNKNOWN, false,
+                "Expected %d rows, but read %d.",
+                tableNumRows, table->n);
+        return 3;
+    }
+
+
+    for (int row = 0; row < table->n; row++) {
+        psMetadata* rowData = table->data[row];
+
+        psS32 intItem = psMetadataLookupS32(rowData, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(rowData, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(rowData, "MYDBL",NULL);
+        psBool boolItem = psMetadataLookupBool(rowData, "MYBOOL",NULL);
+
+        if (intItem != row) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file (row=%d).  Got %d vs %d",
+                    row, intItem, row);
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+row)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file (row=%d).  Got %f vs %f",
+                    row, fltItem,1.0f/(float)(1+row));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+row)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file (row=%d).  Got %g vs %g",
+                    row, dblItem, 1.0/(double)(1+row));
+            return 22;
+        }
+
+        if ( boolItem != ((row&0x01) == 0)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file (row=%d). Got %d vs %d",
+                    row, boolItem, ((row&0x01) == 0));
+            return 23;
+        }
+
+    }
+
+    psFree(table);
+    psFree(fits);
+
+    psArray* nullTest = psFitsReadTable(NULL);
+
+    if (nullTest != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadTable returned non-NULL when given NULL.");
+        return 30;
+    }
+
+    return 0;
+}
+
+psS32 testImageRead(void)
+{
+    psS32 N = 256;
+    psS32 M = 128;
+
+    /*
+        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; \
+        /*        psImagimge* 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); \
+        psFits* fits = psFitsAlloc(filename); \
+        psRegion region = {0,0,0,0}; \
+        if (! psFitsWriteImage(fits, NULL, img, 2, "primary")) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 1; \
+        } \
+        if (! psFitsUpdateImage(fits,img3, region, 1)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 2; \
+        } \
+        if (! psFitsWriteImage(fits,NULL, img3, 2, "extension")) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 3; \
+        } \
+        if (! psFitsUpdateImage(fits,img,region, 1)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 4; \
+        } \
+        psFree(img); \
+        psFree(fits); \
+        img = NULL; \
+        psFree(img3); \
+        img3 = NULL; \
+        fits = psFitsAlloc(filename); \
+        psRegion reg = {readM0, readM, readN0, readN}; \
+        img = psFitsReadImage(img, fits, reg, 0); \
+        img3 = psFitsReadImage(img3, fits, reg, 1); \
+        if (img3 == NULL) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 6; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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; \
+        psFitsMoveExtNum(fits,1, false); \
+        img3 = psFitsReadImage(img3, fits, reg, 0); \
+        img = psFitsReadImage(img, fits, reg, 1); \
+        if (img == NULL) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 9; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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); \
+        psFree(fits); \
+    }
+
+    #define testReadType(TYP,filename) \
+    testReadTypeSize(1,1,0,0,0,0,TYP,"tmpImages/1x1_" filename); \
+    testReadTypeSize(M,1,M/4,0,M*3/4,0,TYP,"tmpImages/Mx1_" filename); \
+    testReadTypeSize(1,N,0,N/4,0,N*3/4,TYP,"tmpImages/1xN_" filename); \
+    testReadTypeSize(M,N,M/4,N/4,M*3/4,N*3/4,TYP,"tmpImages/MxN_" filename);
+
+    mkdir("tmpImages",0777);
+
+    testReadTypeSize(1,1,0,0,0,0,U8,"tmpImages/1x1_" "U8.fits");
+    testReadTypeSize(M,1,M/4,0,M*3/4,0,U8,"tmpImages/Mx1_" "U8.fits");
+    testReadTypeSize(1,N,0,N/4,0,N*3/4,U8,"tmpImages/1xN_" "U8.fits");
+    testReadTypeSize(M,N,M/4,N/4,M*3/4,N*3/4,U8,"tmpImages/MxN_" "U8.fits");
+
+
+    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");
+
+    return 0;
+}
+
+psS32 testImageWrite(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psS32 m = 64;
+    psS32 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
+        ("tmpImages/writeTest.fits");
+    psRegion region = {
+                          0,0,0,0
+                      };
+    psFits* fits = psFitsAlloc("tmpImages/writeTest.fits");
+
+    if (! psFitsWriteImage(fits, NULL, img,1,NULL)) {
+        psError(PS_ERR_UNKNOWN, true,"Couldn't write writeTest.fits.");
+        return 14;
+    }
+    if (! psFitsUpdateImage(fits, img2, region, 0)) {
+        psError(PS_ERR_UNKNOWN, true,"Couldn't update writeTest.fits.");
+        return 15;
+    }
+    psFree(img);
+    psFree(img2);
+
+    // Did it really overwrite the pixel values?  Let's read it in and see.
+    psFree(fits);
+    fits = psFitsAlloc("tmpImages/writeTest.fits");
+    img = psFitsReadImage(NULL, fits, region, 0);
+    if (img == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"Could not read in writeTest.fits.");
+        return 16;
+    }
+    for (psU32 row=0;row<n;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(imgRow[col] - (row+2*col)) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"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 ( psFitsWriteImage(fits,NULL,NULL, 1, NULL) ) {
+        psError(PS_ERR_UNKNOWN, true,"psImageWriteSection did not return false when input image is NULL.");
+        return 20;
+    }
+
+    psFree(fits);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/fileUtils/tst_psLookupTable_01.c
===================================================================
--- /branches/rel4/psLib/test/fileUtils/tst_psLookupTable_01.c	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/tst_psLookupTable_01.c	(revision 3057)
@@ -0,0 +1,125 @@
+/** @file  tst_psLookupTable_01.c
+*
+*  @brief Test driver for psLookupTable functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read table and interpolate value
+*     Test B - Read table and interpolate all values
+*     Test C - Read beyond lower table bound
+*     Test D - Read beyond upper table bound
+*     Test E - Free data
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-12-23 19:38:38 $
+*
+*  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[])
+{
+
+
+    // Test A - Read table and interpolate value
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read table and interpolate value");
+    psLookupStatusType status1 = 0;
+    psF64 index1 = 2450905.0;
+    psF64 out1 = 0.0;
+    psLookupTable* table1 = NULL;
+
+    table1 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table1 = psLookupTableRead(table1);
+    out1 = psLookupTableInterpolate(table1, index1, 0, &status1);
+    if(fabs(out1-31.5)>FLT_EPSILON) {
+        printf("ERROR: Incorrect value, %lf. Expected 31.5\n", out1);
+    } else if(status1 != PS_LOOKUP_SUCCESS) {
+        printf("ERROR: Bad return status, %d\n", status1);
+    }
+    printFooter(stdout, "psMetadata", "Test A - Read table and interpolate value", true);
+
+
+    // Test B - Read table and interpolate all values
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read table and interpolate all values");
+    psU64 i = 0;
+    psF64 index2 = 2450905.0;
+    psVector *out2 = NULL;
+    psLookupTable* table2 = NULL;
+    psVector *stats2 = NULL;
+    psF64 truthData2[] = {31.5, 41317, 0};
+
+    table2 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table2 = psLookupTableRead(table2);
+    stats2 = psVectorAlloc(table2->numCols, PS_TYPE_U32);
+    out2 = psLookupTableInterpolateAll(table2, index2, stats2);
+
+    for(i=0; i<table2->numCols; i++) {
+        if(fabs(out2->data.F64[i]-truthData2[i])>FLT_EPSILON) {
+            printf("ERROR: Incorrect value, %lf. Expected %lf\n", out2->data.F64[i], truthData2[i]);
+        } else if(status1 != PS_LOOKUP_SUCCESS) {
+            printf("ERROR: Bad return status, %d for column %lld\n", stats2->data.U32[i], (long long int)i);
+        }
+    }
+    printFooter(stdout, "psMetadata", "Test B - Read table and interpolate all values", true);
+
+
+    // Test C - Read beyond lower table bound
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read beyond lower table bound");
+    psLookupStatusType status3 = 0;
+    psF64 index3 = 2451179.7;
+    psF64 out3 = 0.0;
+    psLookupTable* table3 = NULL;
+
+    table3 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table3 = psLookupTableRead(table3);
+    out3 = psLookupTableInterpolate(table3, index3, 0, &status3);
+    if(status3 != PS_LOOKUP_PAST_BOTTOM) {
+        printf("ERROR: Bad return status, %d\n", status3);
+    }
+    printFooter(stdout, "psMetadata", "Test C - Read beyond lower table bound", true);
+
+    // Test D - Read beyond upper table bound
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Read beyond upper table bound");
+    psLookupStatusType status4 = 0;
+    psF64 index4 = 0.0;
+    psF64 out4 = 0.0;
+    psLookupTable* table4 = NULL;
+
+    table4 = psLookupTableAlloc("../../data/tai_utc.dat", 0, 2451179.6);
+    table4 = psLookupTableRead(table4);
+    out4 = psLookupTableInterpolate(table4, index4, 0, &status4);
+    if(status4 != PS_LOOKUP_PAST_TOP) {
+        printf("ERROR: Bad return status, %d\n", status4);
+    }
+    printFooter(stdout, "psMetadata", "Test D - Read beyond upper table bound", true);
+
+
+    // Test E - Free data
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Free data");
+    psFree(table1);
+    psFree(table2);
+    psFree(table3);
+    psFree(table4);
+    psFree(out2);
+    psFree(stats2);
+    if (psMemCheckLeaks(0, NULL, stdout, false)) {
+        psError(PS_ERR_UNKNOWN,true,"Memory leaks detected");
+        return 10;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test E - Free data", true);
+
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/fileUtils/verified/tst_psFits.stderr
===================================================================
--- /branches/rel4/psLib/test/fileUtils/verified/tst_psFits.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/verified/tst_psFits.stderr	(revision 3057)
@@ -0,0 +1,125 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsAlloc}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psFitsAlloc} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsMoveExtName}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    Could not find HDU 'bogus' in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtName
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtName (psFits.c:<LINENO>)
+    Specified extension name can not be NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsMoveExtName} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsMoveExtNum}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsGetSize (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move to specified HDU #-1 in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move -1 HDUs from current position in file multi.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move to specified HDU #8 in file multi.fits.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    Could not move 1 HDUs from current position in file multi.fits.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|tst_psFitsMoveExtNum
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psFitsMoveExtNum (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsMoveExtNum} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadHeader}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psFitsReadHeader
+    following should be an error (input psFits = NULL)
+<DATE><TIME>|<HOST>|E|psFitsReadHeader (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadHeader} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadHeaderSet}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psFitsReadHeaderSet (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadHeaderSet} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadTable}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psFitsReadTable (psFits.c:<LINENO>)
+    The input psFits object can not NULL.
+
+---> TESTPOINT PASSED (psImage{psFitsReadTable} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsReadImage}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psFitsReadImage} | tst_psFits.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFits.c                                               *
+*            TestPoint: psImage{psFitsWriteImage}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should generate an error message because input image is null.
+<DATE><TIME>|<HOST>|E|psFitsWriteImage (psFits.c:<LINENO>)
+    The input psImage was NULL.  Need a non-NULL psImage for operation to be performed.
+
+---> TESTPOINT PASSED (psImage{psFitsWriteImage} | tst_psFits.c)
+
Index: /branches/rel4/psLib/test/fileUtils/verified/tst_psLookupTable_01.stdout
===================================================================
--- /branches/rel4/psLib/test/fileUtils/verified/tst_psLookupTable_01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/fileUtils/verified/tst_psLookupTable_01.stdout	(revision 3057)
@@ -0,0 +1,45 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test A - Read table and interpolate value}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test A - Read table and interpolate value} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test B - Read table and interpolate all values} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Read table and interpolate all values} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test C - Read beyond lower table bound}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Read beyond lower table bound} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test D - Read beyond upper table bound}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Read beyond upper table bound} | tst_psLookupTable_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLookupTable_01.c                                     *
+*            TestPoint: psMetadata{Test E - Free data}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Free data} | tst_psLookupTable_01.c)
+
Index: /branches/rel4/psLib/test/image/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/image/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/image/.cvsignore	(revision 3057)
@@ -0,0 +1,14 @@
+temp
+tst_psImage
+tst_psImageExtraction
+tst_psImageFFT
+tst_psImageManip
+tst_psImageStats00
+tst_psImageStats01
+tst_psImageStats02
+tst_psImageStats03
+tst_psImageConvolve
+tst_psImageIO
+tmpImages
+tst_psImageStats04
+tst_psImageInterpolate
Index: /branches/rel4/psLib/test/image/Makefile
===================================================================
--- /branches/rel4/psLib/test/image/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/image/Makefile	(revision 3057)
@@ -0,0 +1,55 @@
+################################################################################
+##
+##  Makefile:   test/collections
+##
+##  $Revision: 1.7 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-12-17 19:48:49 $
+##
+##  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_psImageStats04 \
+tst_psImageExtraction \
+tst_psImageConvolve \
+tst_psImageIO \
+tst_psImageInterpolate
+
+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/rel4/psLib/test/image/tst_psImage.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImage.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImage.c	(revision 3057)
@@ -0,0 +1,455 @@
+/** @file  tst_psImage.c
+ *
+ *  @brief Contains the tests for psImage.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-04 02:34: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 psS32 testImageAlloc(void);
+static psS32 testImageCopy(void);
+static psS32 testRegion(void);
+
+testDescription tests[] = {
+                              {testImageAlloc,546,"psImageAlloc",0,false},
+                              {testImageAlloc,548,"psImageFree",0,true},
+                              {testImageCopy,551,"psImageCopy",0,false},
+                              {testRegion,790,"psRegionAlloc",0,false},
+                              {testRegion,791,"psRegionFromString",0,true},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+psS32 testImageAlloc(void)
+{
+    psImage* image = NULL;
+    psU32 sizes = 6;
+    psU32 numCols[] = {
+                          0,1,1,100,100,150
+                      };
+    psU32 numRows[] = {
+                          0,1,100,1,150,100
+                      };
+    psU32 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 (psU32 t=0;t<types;t++) {
+        psLogMsg(__func__,PS_LOG_INFO,"Testing psImage with type %xh",type[t]);
+
+        for (psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageAlloc returned row0/col0 of %d/%d.  Should be 0/0.",
+                        image->row0, image->row0);
+                psFree(image);
+                return 4;
+            }
+
+            if (image->parent != NULL) {
+                psError(PS_ERR_UNKNOWN, true,"psImageAlloc returned non-NULL parent");
+                psFree(image);
+                return 5;
+            }
+
+            if (image->children != NULL) {
+                psError(PS_ERR_UNKNOWN, true,"psImageAlloc returned non-NULL children array");
+                psFree(image);
+                return 7;
+            }
+
+            switch (type[t]) {
+            case PS_TYPE_U16: {
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i];
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.U16[r][c] = 2*c+r;
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            if (image->data.U16[r][c] != 2*c+r) {
+                                psError(PS_ERR_UNKNOWN, true,"Could not set all pixels in uint16 image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F32: {
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i];
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.F32[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            if (fabsf(image->data.F32[r][c] - (2.0f*c+r)) > FLT_EPSILON) {
+                                psError(PS_ERR_UNKNOWN, true,"Could not set all pixels in float image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F64: {
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i];
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.F64[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            if (fabs(image->data.F64[r][c] - (2.0f*c+r)) > DBL_EPSILON) {
+                                psError(PS_ERR_UNKNOWN, true,"Could not set all pixels in double image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_C32: {
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i];
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.C32[r][c] = r + I * c;
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 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(PS_ERR_UNKNOWN, true,"Could not set all pixels in complex image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_PTR: {
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i];
+                    psImage* temp = psImageAlloc(1,1,PS_TYPE_F32);
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.PTR[r][c] = psMemIncrRefCounter(temp);
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            if (image->data.PTR[r][c] != temp) {
+                                psError(PS_ERR_UNKNOWN, true, "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.
+                    psU32 rows = numRows[i];
+                    psU32 cols = numCols[i]*PSELEMTYPE_SIZEOF(type[t]);
+
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            image->data.U8[r][c] = (uint8_t)(r + c);
+                        }
+                    }
+                    for (psS32 r=0;r<rows;r++) {
+                        for (psS32 c=0;c<cols;c++) {
+                            if (image->data.U8[r][c] != (uint8_t)(r + c)) {
+                                psError(PS_ERR_UNKNOWN, true,"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;
+}
+
+psS32 testImageCopy(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* img4 = NULL;
+    psU32 c = 128;
+    psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"output image doesn't exist");
+        return 4;
+    }
+    if (img4->type.type != img->type.type) {
+        psError(PS_ERR_UNKNOWN, true,"output image is not the same type as input image");
+        return 4;
+    }
+    for (psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageCopy failed to copy U8."); \
+        return 2; \
+    } \
+    for (psU32 row=0;row<r;row++) { \
+        ps##IN* imgRow = img->data.IN[row]; \
+        ps##OUT* img2Row = img2->data.OUT[row]; \
+        for (psU32 col=0;col<c;col++) { \
+            if (abs(imgRow[col] - (ps##IN)(row+col)) > 0.5) { \
+                psError(PS_ERR_UNKNOWN, true,"Input image was changed at %d,%d!", \
+                        col,row); \
+                return 2; \
+            } \
+            if (abs(img2Row[col] - (ps##OUT)(imgRow[col])) > 0.5) { \
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageCopy didn't return NULL when input image was NULL.");
+        return 3;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(img4);
+
+    return 0;
+}
+
+static psS32 testRegion(void)
+{
+    int testNum = 0;
+
+
+    // Testpoint #790
+
+    psRegion* region = psRegionAlloc(1,2,3,4);
+
+    testNum++;
+    if (region == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psRegionAlloc returned a NULL pointer.");
+        return testNum;
+    }
+
+    testNum++;
+    if (region->x0 != 1 || region->x1 != 2 || region->y0 != 3 || region->y1 != 4) {
+        psError(PS_ERR_UNKNOWN, false,
+                "The region attributes are not set properly (%s)",
+                psRegionToString(region));
+        return testNum;
+    }
+
+    psFree(region);
+
+    // Testpoint #791
+
+    region = psRegionFromString("[1:2,3:4]");
+
+    testNum++;
+    if (region == NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psRegionFromString returned a NULL pointer.");
+        return testNum;
+    }
+
+    testNum++;
+    if (region->x0 != 1 || region->x1 != 2 || region->y0 != 3 || region->y1 != 4) {
+        psError(PS_ERR_UNKNOWN, false,
+                "The region attributes are not set properly (%s)",
+                psRegionToString(region));
+        return testNum;
+    }
+
+    psFree(region);
+    region = psRegionFromString("[1:2,3:]");
+
+    testNum++;
+    if (region != NULL) {
+        psError(PS_ERR_UNKNOWN, false,
+                "psRegionFromString returned a non-NULL pointer given a malformed string.");
+        return testNum;
+    }
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/image/tst_psImageConvolve.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageConvolve.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageConvolve.c	(revision 3057)
@@ -0,0 +1,452 @@
+/** @file  tst_psImageConvolve.c
+ *
+ *  @brief Contains the tests for psImageConvolve.[ch]
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-05 21:16:15 $
+ *
+ *  Copyright 2004-2005 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 psS32 testKernelAlloc(void);
+static psS32 testKernelGenerate(void);
+//static psS32 testImageConvolve(void);
+
+testDescription tests[] = {
+                              {testKernelAlloc,731,"psKernelAlloc",0,false},
+                              {testKernelGenerate,732,"psKernelGenerate",0,false},
+                              //                              {testImageConvolve,733,"psImageConvolve",0,false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+static psS32 testKernelAlloc(void)
+{
+    psS32 numCases = 4;
+    psS32 xMin[] = { -5,  0,-10,  5};
+    psS32 xMax[] = {  0,  5, -5, 10};
+    psS32 yMin[] = { -4,  0, -8,  4};
+    psS32 yMax[] = {  0,  4, -4,  8};
+    psS32 i;
+    psKernel* k;
+
+    for (i=0;i<numCases;i++) {
+        k = psKernelAlloc(xMin[i],xMax[i],yMin[i],yMax[i]);
+
+        if (k == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 (psS32 j=yMin[i]; j<yMax[i]; j++) {
+            if (k->kernel[j]+xMin[i] != k->image->data.PS_TYPE_KERNEL_DATA[j-yMin[i]]) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psKernelAlloc returned NULL for xMin > xMax.");
+        return i*10+5;
+    }
+
+    if (k->xMin != -5 || k->xMax != 5) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psKernelAlloc returned NULL for yMin > yMax.");
+        return i*10+7;
+    }
+
+    if (k->yMin != -5 || k->yMax != 5) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelAlloc didn't swap yMin & yMax.");
+        return i*10+8;
+    }
+
+    psFree(k);
+
+    return 0;
+}
+
+static psS32 testKernelGenerate(void)
+{
+    psS32 size = 5;
+    psS32 t[] = { 1, 2, 8, 9, 10 };
+    psS32 x[] = { 0, 1, 0, -1, 0 };
+    psS32 y[] = { 2, 1, -1, -2, 0 };
+    psKernelType sum;
+
+    psVector* xVec = psVectorAlloc(size,PS_TYPE_U32);
+    psVector* yVec = psVectorAlloc(size,PS_TYPE_U32);
+    psVector* tVec = psVectorAlloc(size,PS_TYPE_U32);
+
+    for (psS32 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(PS_ERR_UNKNOWN, true,"psKernelGenerate returned NULL.");
+        return 1;
+    }
+
+    if (result->xMin != -1 || result->xMax != 1 ||
+            result->yMin != -2 || result->yMax != 2) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate result had a range of [%d:%d,%d:%d].  Suppose to be [-2:2,-1:1].",
+                result->xMin, result->xMax, result->yMin, result->yMax);
+        return 2;
+    }
+
+    sum = 0.0;
+    printf("Resulting kernel:\n");
+    for (psS32 y = result->yMin; y <= result->yMax; y++) {
+        for (psS32 x = result->xMin; x <= result->xMax; x++) {
+            printf(" %6.2f ", result->kernel[y][x]);
+            sum += result->kernel[y][x];
+        }
+        printf("\n");
+    }
+    if (fabsf(1.0 - sum) > FLT_EPSILON) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate result is not normalized (sum=%g).",
+                sum);
+
+        return 3;
+
+    }
+
+    if (fabsf(result->kernel[-2][0] - 0.1) > FLT_EPSILON ||
+            fabsf(result->kernel[ -1][ -1] - 0.1) > FLT_EPSILON ||
+            fabsf(result->kernel[ 1][ 0] - 0.6) > FLT_EPSILON ||
+            fabsf(result->kernel[2][1] - 0.1) > FLT_EPSILON) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate result values, %g,%g,%g,%g, are wrong. Suppose to be 0.1,0.1,0.6,0.1",
+                result->kernel[-2][0], result->kernel[-1][-1],
+                result->kernel[1][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 (psS32 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(PS_ERR_UNKNOWN, true,"psKernelGenerate returned NULL.");
+        return 5;
+    }
+
+    if (result->xMin != 0 || result->xMax != 1 ||
+            result->yMin != 0 || result->yMax != 3) {
+        psError(PS_ERR_UNKNOWN, true,"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;
+    printf("Resulting kernel (relative=true):\n");
+    for (psS32 y = result->yMin; y <= result->yMax; y++) {
+        for (psS32 x = result->xMin; x <= result->xMax; x++) {
+            printf(" %6.2f ", result->kernel[y][x]);
+            sum += result->kernel[y][x];
+        }
+        printf("\n");
+    }
+    if (fabsf(1.0 - sum) > FLT_EPSILON) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate result is not normalized (sum=%g).",
+                sum);
+
+        return 7;
+
+    }
+
+    if (fabsf(result->kernel[0][0] - 19.0/30.0) > FLT_EPSILON ||
+            fabsf(result->kernel[2][0] - 1.0/30.0) > FLT_EPSILON ||
+            fabsf(result->kernel[2][1] - 8.0/30.0) > FLT_EPSILON ||
+            fabsf(result->kernel[3][1] - 2.0/30.0) > FLT_EPSILON) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate result values, %g,%g;%g,%g, are wrong. Suppose to be 2,6;1,0.",
+                result->kernel[0][0], result->kernel[2][0],
+                result->kernel[2][1], result->kernel[3][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 (psS32 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 an error.");
+    result = psKernelGenerate(tVec, xVec, yVec, false);
+    if (result != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psKernelGenerate returned non-NULL given differing sized vectors.");
+        return 9;
+    }
+
+    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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psKernelGenerate returned a kernel with no y vector.");
+        return 11;
+    }
+
+    psFree(xVec);
+    psFree(yVec);
+    psFree(tVec);
+    psFree(result);
+
+    return 0;
+}
+
+/*
+static psS32 testImageConvolve(void)
+{
+    const psS32 r = 200;
+    const psS32 c = 300;
+    psS32 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 (psS32 i=0;i<2;i++) {
+        for (psS32 j=0;j<2;j++) {
+            nsk->kernel[i][j] = i+j;
+            sum = i+j;
+        }
+    }
+    for (psS32 i=0;i<2;i++) {
+        for (psS32 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(PS_ERR_UNKNOWN, true, "psImageConvolve returned a NULL for direct gaussian case.");
+        return 1;
+    }
+ 
+    if (out->numCols != c || out->numRows != r) {
+        psError(PS_ERR_UNKNOWN, true, "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(PS_ERR_UNKNOWN, true, "psImageConvolve result image is of type %s, not psF32.",
+                typeStr);
+        return 3;
+    }
+ 
+    // test values
+    for (psS32 i=-1;i<1;i++) {
+        for (psS32 j=-1;j<1;j++) {
+            if (fabsf(out->data.F32[r/2+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true, "psImageConvolve returned a NULL for gaussian case.");
+        return 10;
+    }
+ 
+    if (out != out2) {
+        psError(PS_ERR_UNKNOWN, true, "psImageConvolve didn't recycle the supplied out image struct.");
+        return 11;
+    }
+ 
+    if (out->numCols != c || out->numRows != r) {
+        psError(PS_ERR_UNKNOWN, true, "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(PS_ERR_UNKNOWN, true, "psImageConvolve result image is of type %s, not psF32.",
+                typeStr);
+        return 13;
+    }
+ 
+    psImageWriteSection(out2,0,0,0,NULL,0,"out2.fits");
+    // test values
+    for (psS32 i=-1;i<1;i++) {
+        for (psS32 j=-1;j<1;j++) {
+            if (fabsf(out->data.F32[r/2+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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/rel4/psLib/test/image/tst_psImageExtraction.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageExtraction.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageExtraction.c	(revision 3057)
@@ -0,0 +1,1434 @@
+/** @file  tst_psImageExtraction.c
+*
+*  @brief Contains the tests for psImageExtraction.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-11-04 01:05:00 $
+*
+*  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 psS32 testImageSlice(void);
+static psS32 testImageSubset(void);
+static psS32 testImageSubsection(void);
+static psS32 testImageTrim(void);
+static psS32 testImageCut(void);
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    return ! runTestSuite( stderr, "psImage", tests, argc, argv );
+}
+
+psS32 testImageSlice(void)
+{
+    const psS32 r = 200;
+    const psS32 c = 300;
+    const psS32 m = r / 2 -1;
+    const psS32 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 ( psS32 row = 0;row < r;row++ ) {
+        psMaskType* maskRow = mask->data.PS_TYPE_MASK_DATA[row];
+        for ( psS32 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 ( psS32 row = 0;row < r;row++ ) { \
+        ps##TYPE *imageRow = image->data.TYPE[ row ]; \
+        ps##TYPE rowOffset = row * 2; \
+        for ( psS32 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(PS_ERR_UNKNOWN,true,"Number of results is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+1; \
+    } \
+    \
+    if (positions->n != TRUTH_SIZE) { \
+        psError(PS_ERR_UNKNOWN,true,"Number of results for positions vector is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+2; \
+    } \
+    \
+    for (psS32 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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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( PS_ERR_UNKNOWN,true, "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
+psS32 testImageSubset(void)
+{
+    psImage preSubsetStruct;
+    psImage* original;
+    psImage* subset1 = NULL;
+    psImage* subset2 = NULL;
+    psImage* subset3 = NULL;
+    psS32 c = 128;
+    psS32 r = 256;
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (psS32 row=0;row<r;row++) {
+        for (psS32 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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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 (psS32 row=0;row<r/2;row++) {
+        for (psS32 col=0;col<c/2;col++) {
+            if (subset2->data.U32[row][col] != original->data.U32[row+r/4][col+c/4]) {
+                psError(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when numCols=0.");
+        return 16;
+    }
+    if (memcmp(original,&preSubsetStruct,sizeof(psImage)) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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
+psS32 testImageSubsection(void)
+{
+    psImage* original;
+    psImage* subset;
+    psS32 c = 128;
+    psS32 r = 256;
+    psS32 i;
+    psS32 numRegions = 4;
+    psS32 x1[] = {  0, 32, 64, 32};
+    psS32 x2[] = { 32, 64,127, 64};
+    psS32 y1[] = {  0, 32, 32,128};
+    psS32 y2[] = { 32, 64, 64,255};
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (psS32 row=0;row<r;row++) {
+        for (psS32 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(PS_ERR_UNKNOWN,true,"psImageSubsection returned a NULL with a subset of %s.",
+                    sectionStr);
+            return 10*i+1;
+        }
+
+        if (subset->type.type != PS_TYPE_U32) {
+            psError(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set parent.");
+            return 10*i+4;
+        }
+
+        if (subset->children != NULL) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set children to NULL.");
+            return 10*i+5;
+        }
+
+        if (original->children == NULL || original->children->n != i+1) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't increment number of children by one per subset.");
+            return 10*i+6;
+        }
+
+
+        if (original->children->data[i] != subset) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't properly store the children pointer.");
+            return 10*i+7;
+        }
+
+        psS32 numCols = x2[i]-x1[i]+1;
+        psS32 numRows = y2[i]-y1[i]+1;
+        if (subset->numCols != numCols || subset->numRows != numRows) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection output size was not proper(%dx%d, should be %dx%d).",
+                    subset->numCols, subset->numRows, numCols, numRows);
+            return 10*i+8;
+        }
+
+        for (psS32 row=0;row<numRows;row++) {
+            for (psS32 col=0;col<numCols;col++) {
+                if (subset->data.U32[row][col] != original->data.U32[row+y1[i]][col+x1[i]]) {
+                    psError(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN,true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was NULL.");
+        return 10*i+18;
+    }
+
+    psFree(original);
+
+    return 0;
+}
+
+static psS32 testImageTrim(void)
+{
+    psS32 r = 200;
+    psS32 c = 300;
+    psS32 qtrR = r/4;
+    psS32 qtrC = c/4;
+    psS32 halfR = r/2;
+    psS32 halfC = c/2;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 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 (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 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 (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 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 (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 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 psS32 testImageCut(void)
+{
+    psS32 c = 300;
+    psS32 r = 200;
+    psS32 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};
+    psBool success[] = {true,true,true,true,true,true,true,false,false,false,false,false,false,false,false};
+    psU32 length = 100;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 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 (psS32 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 (psS32 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 psS32 testImageRadialCut(void)
+{
+    psS32 c = 300;
+    psS32 r = 200;
+    psS32 centerX = c/2;
+    psS32 centerY = r/2;
+    psErr* err = NULL;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 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 (psS32 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 (psS32 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 (psS32 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/rel4/psLib/test/image/tst_psImageFFT.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageFFT.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageFFT.c	(revision 3057)
@@ -0,0 +1,663 @@
+/** @file  tst_psImageFFT.c
+ *
+ *  @brief Contains the tests for psFFT.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-15 03:57:03 $
+ *
+ *  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 (psU32 row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (psU32 col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static psS32 testImageFFT(void);
+static psS32 testImageRealImaginary(void);
+static psS32 testImageComplex(void);
+static psS32 testImageConjugate(void);
+static psS32 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}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return (! runTestSuite(stderr,"psFFT",tests,argc,argv) );
+}
+
+psS32 testImageFFT(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psU32 m = 128;
+    psU32 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(PS_ERR_UNKNOWN, true,"FFT didn't produce complex values?");
+        return 1;
+    }
+    if (img2->numCols != m || img2->numRows != n) {
+        psError(PS_ERR_UNKNOWN, true,"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 (psU32 row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        for (psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"FFT didn't produce complex values?");
+        return 5;
+    }
+
+    if (img3->numCols != m || img3->numRows != n) {
+        psError(PS_ERR_UNKNOWN, true,"FFT didn't produce proper size result (%dx%d vs. expected %dx%d).",
+                img3->numCols,img3->numRows,m,n);
+        return 6;
+    }
+
+    for (psU32 row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        psF32* imgRow = img->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            psF32 pixel = creal(img3Row[col])/m/n;
+            if (fabsf(pixel-imgRow[col]) > 0.1) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"FFT asked to make real result, but I got a %s type image?",typeStr);
+        return 8;
+    }
+
+    if (img3->numCols != m || img3->numRows != n) {
+        psError(PS_ERR_UNKNOWN, true,"FFT didn't produce proper size result (%dx%d vs. expected %dx%d).",
+                img3->numCols,img3->numRows,m,n);
+        return 9;
+    }
+
+    for (psU32 row=0;row<n;row++) {
+        psF32* img3Row = img3->data.F32[row];
+        psF32* imgRow = img->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            psF32 pixel = img3Row[col]/m/n;
+            if (fabsf(pixel-imgRow[col]) > 0.1) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageFFT should return null for an invalid FFT direction.");
+        return 11;
+    }
+    psFree(img4);
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+
+    return 0;
+}
+
+psS32 testImageRealImaginary(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* c64Img = NULL;
+    psImage* c64Img2 = NULL;
+    psImage* c64Img3 = NULL;
+    psImage* ncImg = NULL;
+    psImage* ncImg2 = NULL;
+    psImage* ncImg3 = NULL;
+
+    psU32 m = 128;
+    psU32 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(PS_ERR_UNKNOWN, true,"psImageReal returned a NULL?");
+        return 1;
+    }
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN, true,"psImageReal returned a wrong type (%d)?",
+                img2->type.type);
+        return 2;
+    }
+
+    img3 = psImageImaginary(img3,img);
+    if (img3 == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageImaginary returned a NULL?");
+        return 3;
+    }
+    if (img3->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN, true,"psImageImaginary returned a wrong type (%d)?",
+                img3->type.type);
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for (psU32 row=0;row<n;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        psF32* img3Row = img3->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageReal didn't return the real portion at n=%d",
+                        n);
+                return 5;
+            }
+            if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageImaginary didn't return the imag portion at n=%d",
+                        n);
+                return 6;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+
+    /*
+    1. create a C64 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 C64 complex vector with distinctly different real and imaginary parts.
+    GENIMAGE(c64Img,m,n,C64, row + I * col);
+
+    // 2. call psImageReal and psImageImaginary
+    c64Img2 = psImageReal(c64Img2,c64Img);
+    if (c64Img2 == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageReal returned a NULL?");
+        return 1;
+    }
+    if (c64Img2->type.type != PS_TYPE_F64) {
+        psError(PS_ERR_UNKNOWN, true,"psImageReal returned a wrong type (%d)?",
+                img2->type.type);
+        return 2;
+    }
+
+    c64Img3 = psImageImaginary(c64Img3,c64Img);
+    if (c64Img3 == NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageImaginary returned a NULL?");
+        return 3;
+    }
+    if (c64Img3->type.type != PS_TYPE_F64) {
+        psError(PS_ERR_UNKNOWN, true,"psImageImaginary returned a wrong type (%d)?",
+                c64Img3->type.type);
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for (psU32 row=0;row<n;row++) {
+        psF64* img2Row = c64Img2->data.F64[row];
+        psF64* img3Row = c64Img3->data.F64[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageReal didn't return the real portion at n=%d",
+                        n);
+                return 5;
+            }
+            if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageImaginary didn't return the imag portion at n=%d",
+                        n);
+                return 6;
+            }
+        }
+    }
+
+    GENIMAGE(ncImg,m,n,F32,row+col);
+    ncImg2 = psImageReal(ncImg2,ncImg);
+    ncImg3 = psImageImaginary(ncImg3,ncImg);
+    if(ncImg2 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageReal returned NULL");
+        return 40;
+    }
+    if(ncImg2->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psImageReal returned a wrong type");
+        return 41;
+    }
+    if(ncImg3 == NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageImaginary returned NULL");
+        return 42;
+    }
+    if(ncImg3->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psImageImaginary returned NULL");
+        return 43;
+    }
+    for(psU32 row=0; row<n; row++) {
+        psF32* ncImg2Row = ncImg2->data.F32[row];
+        psF32* ncImg3Row = ncImg3->data.F32[row];
+        for(psU32 col=0; col<m; col++) {
+            if(fabsf(ncImg2Row[col] - (row+col)) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImageReal didn't return the real portion");
+                return 45;
+            }
+            if(fabsf(ncImg3Row[col] - 0) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImageImaginary didn't return the imaginary portion");
+                return 46;
+            }
+        }
+    }
+    psFree(ncImg);
+    psFree(ncImg2);
+    psFree(ncImg3);
+
+    psFree(c64Img);
+    psFree(c64Img2);
+    psFree(c64Img3);
+
+    // Perform psImageReal with null input
+    if(psImageReal(NULL,NULL) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImageReal did not return null with null input");
+        return 10;
+    }
+
+    // Perform psImageImaginary with null input
+    if(psImageImaginary(NULL,NULL) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImageImaginary did not return null with null input");
+        return 10;
+    }
+
+    return 0;
+}
+
+psS32 testImageComplex(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* c64Img = NULL;
+    psImage* c64Img2 = NULL;
+    psImage* c64Img3 = NULL;
+    psImage* pImg = NULL;
+    psImage* pImg2 = NULL;
+    psImage* pImg3 = NULL;
+
+    psU32 m = 128;
+    psU32 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);
+    GENIMAGE(c64Img,m,n,F64,row);
+    GENIMAGE(c64Img2,m,n,F64,col);
+    GENIMAGE(pImg,m,n,S16,row);
+    GENIMAGE(pImg2,m,n,S16,col);
+
+    // 2. call psImageComplex
+    img3 = psImageComplex(img3,img,img2);
+    c64Img3 = psImageComplex(c64Img3,c64Img,c64Img2);
+
+    // 3. verify that the result is a psC32
+    if (img3->type.type != PS_TYPE_C32) {
+        psError(PS_ERR_UNKNOWN, true,"Image Type from psImageComplex is not complex? (%d)",
+                img3->type.type);
+        return 1;
+    }
+    if (c64Img3->type.type != PS_TYPE_C64) {
+        psError(PS_ERR_UNKNOWN,true,"Image type from psImageComplex is not complex");
+        return 10;
+    }
+
+    // 4. call psImageReal and psImageImaginary on step 2 results (not needed, just use crealf/cimagf)
+    // 5. compare step 4 results to input.
+    for (psU32 row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        psC64* c64Img3Row = c64Img3->data.C64[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img3Row[col]),cimagf(img3Row[col]));
+                return 2;
+            }
+            if (fabsf(crealf(c64Img3Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(c64Img3Row[col]) - col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImageComplex result is invalid");
+                return 3;
+            }
+        }
+    }
+
+    // 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageComplex returned a image though input sizes mismatched.");
+        return 4;
+    }
+
+    // Perform psImageComplex with invalid type
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+    pImg3 = psImageComplex(pImg3,pImg,pImg2);
+    if ( pImg3 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageComplex did not return NULL");
+        return 50;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(c64Img);
+    psFree(c64Img2);
+    psFree(c64Img3);
+    psFree(pImg);
+    psFree(pImg2);
+
+    // Perform psImageComplex with null input
+    if(psImageComplex(NULL,NULL,NULL) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImageComplex did not return null with null input");
+        return 20;
+    }
+
+    return 0;
+}
+
+psS32 testImageConjugate(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* c64Img = NULL;
+    psImage* c64Img2 = NULL;
+    psImage* pImg = NULL;
+    psImage* pImg2 = NULL;
+
+    psU32 m = 128;
+    psU32 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);
+    GENIMAGE(c64Img,m,n,C64,row + I*col);
+    GENIMAGE(pImg,m,n,F32,row+col);
+
+    // 2. call psImageConjugate
+    img2 = psImageConjugate(img2,img);
+    c64Img2 = psImageConjugate(c64Img2,c64Img);
+    pImg2 = psImageConjugate(pImg2,pImg);
+
+    // 3. verify result is psC32
+    if (img2->type.type != PS_TYPE_C32) {
+        psError(PS_ERR_UNKNOWN, true,"the psImageConjugate didn't return a C32 image.");
+        return 1;
+    }
+    if (c64Img2->type.type != PS_TYPE_C64) {
+        psError(PS_ERR_UNKNOWN,true,"psImageConjugate did not return a C64 image");
+        return 10;
+    }
+    if (pImg2->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN,true,"psImageConjugate did not return a F32 image");
+        return 11;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for (psU32 row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        psC64* c64Img2Row = c64Img2->data.C64[row];
+        psF32* pImg2Row = pImg2->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img2Row[col]),cimagf(img2Row[col]));
+                return 2;
+            }
+            if (fabsf(crealf(c64Img2Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(c64Img2Row[col]) + col) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImageComplex result is invalid");
+                return 20;
+            }
+            if (fabsf(pImg2Row[col] - (row+col)) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImageComplex result is invalid");
+                return 21;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(c64Img);
+    psFree(c64Img2);
+    psFree(pImg);
+    psFree(pImg2);
+
+    // Perform psImageConjugate with null input
+    if(psImageConjugate(NULL,NULL) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImageConjugate did not return null with null input");
+        return 30;
+    }
+
+    return 0;
+}
+
+psS32 testImagePowerSpectrum(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* c64Img = NULL;
+    psImage* c64Img2 = NULL;
+    psImage* pImg = NULL;
+
+    psU32 m = 128;
+    psU32 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);
+    GENIMAGE(c64Img,m,n,C64,row+I*col);
+    GENIMAGE(pImg,m,n,F32,row+col);
+
+    // 2. call psImagePowerSpectrum
+    img2 = psImagePowerSpectrum(img2,img);
+    c64Img2 = psImagePowerSpectrum(c64Img2, c64Img);
+
+    // 3. verify result is psF32
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(PS_ERR_UNKNOWN, true,"the type was not PS_TYPE_F32.");
+        return 1;
+    }
+    if (c64Img2->type.type != PS_TYPE_F64) {
+        psError(PS_ERR_UNKNOWN,true,"psImagePowerSpectrum did not return PS_TYPE_F64");
+        return 10;
+    }
+
+    // 4. verify the values are the square of the absolute values of the original
+    for (psU32 row=0;row<n;row++) {
+        psC32* imgRow = img->data.C32[row];
+        psF32* img2Row = img2->data.F32[row];
+        psC64* c64ImgRow = c64Img->data.C64[row];
+        psF64* c64Img2Row = c64Img2->data.F64[row];
+        for (psU32 col=0;col<m;col++) {
+            psF32 power = cabs(imgRow[col]);
+            psF64 power64 = cabs(c64ImgRow[col]);
+            power *= power/n/n/m/m;
+            power64 *= power64/n/n/m/m;
+
+            if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"psImagePowerSpectrum result is invalid (%d,%d, %.2f vs %.2f)",
+                        col,row,img2Row[col],power);
+                return 2;
+            }
+            if (fabsf(c64Img2Row[col] - power64) > 2.0f*FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN,true,"psImagePowerSpectrum result is invalid");
+                return 22;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(c64Img);
+    psFree(c64Img2);
+
+    // Perform psImagePowerSpectrum with invalid input
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error message.");
+    if(psImagePowerSpectrum(NULL,pImg) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImagePowerSpectrum did not return null with invalid type");
+        return 41;
+    }
+    psFree(pImg);
+
+    // Perform psImagePowerSpectrum with null input
+    if(psImagePowerSpectrum(NULL,NULL) != NULL ) {
+        psError(PS_ERR_UNKNOWN,true,"psImagePowerSpectrum did not return null with null input");
+        return 40;
+    }
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/image/tst_psImageIO.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageIO.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageIO.c	(revision 3057)
@@ -0,0 +1,388 @@
+/** @file  tst_psImageIO.c
+ *
+ *  @brief Contains the tests for psImageIO.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-13 21:15:55 $
+ *
+ *  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 (psU32 row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (psU32 col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static psS32 testImageRead(void);
+static psS32 testImageWrite(void);
+
+testDescription tests[] = {
+                              {
+                                  testImageRead,567,"psImageReadSection",0,false
+                              },
+                              {
+                                  testImageWrite,569,"psImageWriteSection",0,false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psImage",tests,argc,argv)) {
+        psAbort(__FILE__,"One or more tests failed");
+    }
+    return 0;
+}
+
+psS32 testImageRead(void)
+{
+    psS32 N = 256;
+    psS32 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(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 1; \
+        } \
+        if (! psImageWriteSection(img,0,0,0,NULL,0,filename)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 2; \
+        } \
+        if (! psImageWriteSection(img,0,0,1,NULL,1,filename)) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to write test image %s",filename); \
+            return 3; \
+        } \
+        if (! psImageWriteSection(img3,0,0,0,NULL,1,filename)) { \
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageReadSection didn't recycle the psImage?"); */ \
+        /*            return 5; */ \
+        /*        } */ \
+        img3 = psImageReadSection(img3,readM0,readN0,readM,readN,1,NULL,0,filename); \
+        if (img3 == NULL) { \
+            psError(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 6; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Failed to read test image %s",filename); \
+            return 9; \
+        } \
+        for (psU32 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 (psU32 col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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;
+}
+
+psS32 testImageWrite(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psS32 m = 64;
+    psS32 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(PS_ERR_UNKNOWN, true,"Couldn't write writeTest.fits.");
+        return 14;
+    }
+    if (! psImageWriteSection(img2,0,0,0,NULL,0,"tmpImages/writeTest.fits")) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Could not read in writeTest.fits.");
+        return 16;
+    }
+    for (psU32 row=0;row<n;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (psU32 col=0;col<m;col++) {
+            if (fabsf(imgRow[col] - (row+2*col)) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageWriteSection did not return false when input image is NULL.");
+        return 20;
+    }
+
+    /*
+    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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageWriteSection did not return false for invalid extension number.");
+        return 24;
+    }
+
+    psFree(img);
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/image/tst_psImageInterpolate.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageInterpolate.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageInterpolate.c	(revision 3057)
@@ -0,0 +1,282 @@
+/** @file tst_psImageInterpolate.c
+ *
+ * @brief Contains the tests for psImagePixelInterpolate
+ *
+ * @author Eric Van Alst, MHPCC
+ *
+ * @version $Revision: 1.3 $
+ *          $Name: not supported by cvs2svn $
+ * @date $Date: 2004-12-18 02:32:53 $
+ *
+ * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP,valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for(psU32 row=0; row<r; row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for(psU32 col=0; col<c; col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+#define CHECK_INTERP_VALUE(img,x,y,mask,maskval,exposed,TYPE,expected) \
+val = (psF32)psImagePixelInterpolate(img,x,y,mask,maskval,exposed,PS_INTERPOLATE_##TYPE); \
+printf("returned = %.2f    expected = %.2f\n",val,expected); \
+if(val != expected) { \
+    psError(PS_ERR_UNKNOWN,true,"Return value is not as expected."); \
+    return 1; \
+}
+
+#define CHECK_INTERP_BY_TYPE(TYPE) \
+GENIMAGE(img1,10,10,TYPE,row+col) \
+CHECK_INTERP_VALUE(img1,1.9,1.6,NULL,0,0,FLAT,2.0) \
+CHECK_INTERP_VALUE(img1,4.0,2.0,NULL,0,0,BILINEAR,5.0) \
+psFree(img1);
+
+static psS32 testInterpolateFlatBilinear(void);
+static psS32 testInterpolateError(void);
+static psS32 testInterpolateMaskFlatBilinear(void);
+static psS32 testInterpolate1D(void);
+
+testDescription tests[] = {
+                              {testInterpolateFlatBilinear,999,"psImagePixelInterpolate",0,false},
+                              {testInterpolateError,999,"psImagePixelInterpolate",0,false},
+                              {testInterpolateMaskFlatBilinear,999,"psImagePixelInterpolate",0,false},
+                              {testInterpolate1D,999,"psImagePixelInterpolate",0,false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if ( !runTestSuite(stderr,"psImagePixelInterpolate",tests,argc,argv) ) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+psS32 testInterpolateFlatBilinear(void)
+{
+    psImage* img1;
+    psF32 val = 0;
+
+    // Perform simple(four neighbor) FLAT interpolation for all types
+    // Perform bilinear interpolation for all types
+    CHECK_INTERP_BY_TYPE(S8)
+    CHECK_INTERP_BY_TYPE(S16)
+    CHECK_INTERP_BY_TYPE(S32)
+    CHECK_INTERP_BY_TYPE(S64)
+    CHECK_INTERP_BY_TYPE(U8)
+    CHECK_INTERP_BY_TYPE(U16)
+    CHECK_INTERP_BY_TYPE(U32)
+    CHECK_INTERP_BY_TYPE(U64)
+    CHECK_INTERP_BY_TYPE(F32)
+    CHECK_INTERP_BY_TYPE(F64)
+    CHECK_INTERP_BY_TYPE(C32)
+    CHECK_INTERP_BY_TYPE(C64)
+
+    return 0;
+}
+
+psS32 testInterpolateError(void)
+{
+    psF32 val = 0;
+    psImage* img1 = NULL;
+
+    // Perform interpolation with NULL input image and verify return and error message
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    val = psImagePixelInterpolate(img1,1.2,1.2,NULL,0,5.0,PS_INTERPOLATE_FLAT);
+    if(val != 5.0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the unexposed value");
+        return 10;
+    }
+
+    // Perform interpolation with invalid input image type
+    img1 = psImageAlloc(10,10,PS_TYPE_PTR);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    val = psImagePixelInterpolate(img1,1.2,1.2,NULL,0,10.0,PS_INTERPOLATE_FLAT);
+    if(val != 10.0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the unexposed value");
+        return 11;
+    }
+
+    // Perform interpolation with invalid method
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message");
+    val = psImagePixelInterpolate(img1,1.2,1.2,NULL,0,10.0,PS_INTERPOLATE_BILINEAR+1);
+    if(val != 10.0) {
+        psError(PS_ERR_UNKNOWN,true,"Did not return the unexposed value");
+        return 12;
+    }
+
+    psFree(img1);
+
+    return 0;
+}
+
+// The following assumptions about the test image are:
+//
+//                     col
+//             0   1   2   3   4   5   6   7  ...
+//
+// row 0       0   1   2   3   4   5   6   7
+// row 1       1   2   3   4   5   6   7   8
+// row 2       2   3   4   5   6   7   8   9
+// ...
+
+psS32 testInterpolateMaskFlatBilinear(void)
+{
+    psImage* img1 = NULL;
+    psImage* msk1 = NULL;
+    psF32 val = 0;
+
+    // Perform interpolate with mask and mask value set at nearest pixel to verify
+    // the unexposed value is return
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][1] = 1;
+    CHECK_INTERP_VALUE(img1,1.9,1.6,msk1,1,10.0,FLAT,10.0)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (upper left pixel)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.25)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (upper right pixel)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,4.75)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (lower left pixel)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[2][3] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.25)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (lower right pixel)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,4.75)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (upper pixels)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[1][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.5)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (lower pixels)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[2][3] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,4.5)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (left pixels)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[2][3] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.5)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask and one mask value for bilinear (right pixels)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][4] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,4.5)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask only one valid pixel (upper left)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][4] = 1;
+    msk1->data.U8[2][3] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,4.0)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask only one valid pixel (upper right)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[2][3] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.0)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask only one valid pixel (lower left)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[1][4] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,5.0)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask only one valid pixel (lower right)
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[1][4] = 1;
+    msk1->data.U8[2][3] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,6.0)
+    psFree(msk1);
+    psFree(img1);
+
+    // Perform interpolate with mask no valid pixels
+    GENIMAGE(img1,10,10,F32,row+col)
+    GENIMAGE(msk1,10,10,U8,0)
+    msk1->data.U8[1][3] = 1;
+    msk1->data.U8[1][4] = 1;
+    msk1->data.U8[2][3] = 1;
+    msk1->data.U8[2][4] = 1;
+    CHECK_INTERP_VALUE(img1,4.0,2.0,msk1,1,0,BILINEAR,0.0)
+    psFree(msk1);
+    psFree(img1);
+    return 0;
+}
+
+// Perform interpolation for a 1D image
+psS32 testInterpolate1D(void)
+{
+    psImage* img1 = NULL;
+    psF32 val = 0;
+
+    GENIMAGE(img1,10,1,F32,row+col)
+    CHECK_INTERP_VALUE(img1,4.0,0.0,NULL,0,100.0,BILINEAR,3.5)
+
+    psFree(img1);
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/image/tst_psImageManip.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageManip.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageManip.c	(revision 3057)
@@ -0,0 +1,1810 @@
+/** @file  tst_psImageManip.c
+ *
+ *  @brief Contains the tests for psImageManip.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.36 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:04 $
+ *
+ *  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 psS32 testImageClip(void);
+static psS32 testImageClipNAN(void);
+static psS32 testImageClipComplexRegion(void);
+static psS32 testImageOverlay(void);
+static psS32 testImageRebin(void);
+static psS32 testImageRoll(void);
+static psS32 testImageRotate(void);
+static psS32 testImageShift(void);
+static psS32 testImageShiftCase(psS32 cols, psS32 rows, float colShift,float rowShift);
+static psS32 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}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+
+psS32 testImageClip(void)
+{
+    psImage* img = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psF64 min;
+    psF64 max;
+    psS32 numClipped = 0;
+    psS32 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 (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 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 (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    #define testImageClipByComplexType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 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 (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Expected zero return for clips when max < min.");
+        return 4;
+    }
+
+    return 0;
+}
+
+psS32 testImageClipNAN(void)
+{
+    psImage* img = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psS32 numClipped = 0;
+    psS32 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(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%f vs %f) at %d,%d", \
+                        imgRow[col],value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
+        return 4;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+psS32 testImageClipComplexRegion(void)
+{
+    psImage* img = NULL;
+    psU32 c = 1024;
+    psU32 r = 2048;
+    psS32 numClipped = 0;
+    psS32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
+        return 84;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+psS32 testImageOverlay(void)
+{
+
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* img4 = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psS32 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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero with %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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
+                "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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
+                "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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned nonzero eventhough "
+                " overlay image type is different than input image.");
+        return 10;
+    }
+
+    /*
+    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(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero when "
+                "checking divide-by-zero.");
+        return 12;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(img4);
+
+    return 0;
+}
+
+static psS32 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 (psS32 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 (psS32 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 (psS32 row = 0; row<4; row++) { \
+        psF32* meanTruthRow = meanTruth->data.F32[row]; \
+        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row]; \
+        for (psS32 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(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
+        return 1; \
+    } \
+    if (out->numRows != 4 || out->numCols != 4) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 2; \
+    } \
+    for (psS32 row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruth->data.F32[row]; \
+        for (psS32 col = 0; col<4; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out3->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruthWMask->data.F32[row]; \
+        for ( psS32 col = 0; col<4; col++) { \
+            if(abs((psS32)outRow[col]-(psS32)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageRebin didn't recycle a psImage properly!?"); \
+        return 7; \
+    } \
+    if (out == NULL) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
+        return 4; \
+    } \
+    if (out->numRows != 6 || out->numCols != 6) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 5; \
+    } \
+    for (psS32 row = 0; row<6; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = maxTruth->data.F32[row]; \
+        for (psS32 col = 0; col<6; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
+        return 13;
+    }
+
+    psFree(in);
+
+    return 0;
+}
+
+static psS32 testImageRoll(void)
+{
+
+    psImage* in;
+    psImage* out;
+    psImage* out2;
+    psS32 rows = 64;
+    psS32 cols = 64;
+    psS32 rows1 = 8;
+    psS32 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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            inRow[col] = (psF32)row+(psF32)col/1000.0f;
+        }
+    }
+
+    out = psImageRoll(NULL,in,0,0);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageRoll didn't recycle my out psImage!?");
+        return 1;
+    }
+
+    out = psImageRoll(out,in,0,rows/4);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+(cols-cols/4)) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols-cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
+        for (psS32 col=0;col<cols1;col++) { \
+            inRow[col] = (ps##DATATYPE)row+(ps##DATATYPE)col; \
+        } \
+    } \
+    \
+    out = psImageRoll(NULL,in,rows1/4,cols1/4); \
+    for (psS32 row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[(row+rows1/4)%rows1]; \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        for (psS32 col=0;col<cols1;col++) { \
+            if (inRow[(col+cols1/4)%cols1] != outRow[col]) { \
+                psError(PS_ERR_UNKNOWN, true,"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;
+}
+
+psS32 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* fBiOut = NULL;
+    psImage* sBiOut = NULL;
+    psImage* fTruth = NULL;
+    psImage* sTruth = NULL;
+    psImage* fBiTruth = NULL;
+    psImage* sBiTruth = NULL;
+    psS32 rows = 64;
+    psS32 cols = 64;
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+
+    for(psS32 row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (psS32 col=0;col<cols;col++) {
+            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
+            sRow[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");
+    ;
+    psS32 index = 0;
+    psBool fail = false;
+    psF32 radianRot;
+    for (psS32 rot=-180;rot<=180;rot+=45) {
+        psImage* oldOut = fOut;
+        psImage* oldBiOut = fBiOut;
+
+        if (rot == 90) {
+            radianRot = PS_PI_2;
+        } else if (rot == -90) {
+            radianRot = PS_PI+PS_PI_2;
+        } else if (rot == 180 || rot == -180) {
+            radianRot = PS_PI;
+        } else {
+            radianRot = ((float)rot)*PS_PI/180.0;
+        }
+
+        fOut = psImageRotate(fOut,fImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
+        fBiOut = psImageRotate(fBiOut,fImg,radianRot,-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(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
+            return 2;
+        }
+        if (oldBiOut != NULL && oldBiOut != fBiOut) {
+            psError(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
+            return 4;
+        }
+        sOut = psImageRotate(sOut,sImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
+        sBiOut = psImageRotate(sBiOut,sImg,radianRot,-1.0,PS_INTERPOLATE_BILINEAR);
+        if (! psImageWriteSection(fOut,0,0,0,NULL,index,"temp/fOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fOut.fits, so why continue!?");
+            return 20;
+        }
+        if (! psImageWriteSection(sOut,0,0,0,NULL,index,"temp/sOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/sOut.fits, so why continue!?");
+            return 21;
+        }
+        if (! psImageWriteSection(fBiOut,0,0,0,NULL,index,"temp/fBiOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fBiOut.fits, so why continue!?");
+            return 40;
+        }
+        if (! psImageWriteSection(sBiOut,0,0,0,NULL,index,"temp/sBiOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"verified psF32 image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fTruth->numRows != fOut->numRows || fTruth->numCols != fOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<fTruth->numRows;row++) {
+                    psF32* truthRow = fTruth->data.F32[row];
+                    psF32* outRow = fOut->data.F32[row];
+                    for (psS32 col=0;col<fTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"verified psS16 image failed to be read "
+                    "(%d deg. rotation)",rot);
+            fail = true;
+        } else {
+            if (sTruth->numRows != sOut->numRows ||
+                    sTruth->numCols != sOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
+                        "image for %d deg rotation.",rot);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<sTruth->numRows;row++) {
+                    psS16* truthRow = sTruth->data.S16[row];
+                    psS16* outRow = sOut->data.S16[row];
+                    for (psS32 col=0;col<sTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+
+        if (fBiTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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 (psS32 row=0;row<fBiTruth->numRows;row++) {
+                    psF32* truthRow = fBiTruth->data.F32[row];
+                    psF32* outRow = fBiOut->data.F32[row];
+                    for (psS32 col=0;col<fBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sBiTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
+                        "image for %d deg rotation. BILINEAR",rot);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<sBiTruth->numRows;row++) {
+                    psS16* truthRow = sBiTruth->data.S16[row];
+                    psS16* outRow = sBiOut->data.S16[row];
+                    for (psS32 col=0;col<sBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        index++;
+    }
+
+    if (fail) {
+        psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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);
+
+    return 0;
+}
+
+static psS32 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.
+
+    */
+
+    psS32 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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"psImageShift didn't return NULL given an invalid interpolation mode.");
+        return 12;
+    }
+
+    psFree(fImg);
+
+    return 0;
+}
+
+static psS32 testImageShiftCase(psS32 cols,
+                                psS32 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(psS32 row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (psS32 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(psS32 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 (psS32 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(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fRow[col],fValue);
+                return 1;
+            }
+            if (sRow[col] != sValue) {
+                psError(PS_ERR_UNKNOWN, true,"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(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fBiRow[col],fBiValue);
+                return 1;
+            }
+            if (sBiRow[col] != sBiValue) {
+                psError(PS_ERR_UNKNOWN, true,"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 psS32 testImageResample(void)
+{
+
+    psS32 rows = 60;
+    psS32 cols = 80;
+    psImage* result = NULL;
+    psS32 scale = 4;
+    psErr* err;
+
+    psImage* image = psImageAlloc(cols,rows,PS_TYPE_F32);
+    for(psS32 row=0;row<rows;row++) {
+        psF32* imageRow = image->data.F32[row];
+        for (psS32 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(psS32 row=0;row<result->numRows;row++) {
+        for (psS32 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);
+
+    // Verify that that an invalid image type is handled properly
+    psErrorClear();
+    psImage* invImage = psImageAlloc(cols,rows,PS_TYPE_PTR);
+    memset(invImage->rawDataBuffer,0,cols*rows*sizeof(psPtr)); // make sure the image is of all NULLs
+    result = psImageResample(result,invImage,2,PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"return was not NULL, as expected.");
+        return 20;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
+        psLogMsg(__func__,PS_LOG_ERROR,"error message was not appropriate type.");
+        return 21;
+    }
+    psFree(err);
+
+    psFree(image);
+    psFree(result);
+    psFree(invImage);
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/image/tst_psImageStats00.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageStats00.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageStats00.c	(revision 3057)
@@ -0,0 +1,204 @@
+/*****************************************************************************
+   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
+
+psS32 main()
+{
+    psHistogram * myHist = NULL;
+    psHistogram *myHist2 = NULL;
+    psImage *tmpImage = NULL;
+    psImage *tmpMask = NULL;
+    psS32 testStatus = true;
+    psS32 memLeaks = 0;
+    psS32 nb = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 IMAGE_X_SIZE = 0;
+    psS32 IMAGE_Y_SIZE = 0;
+    psS32 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 (%f)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.F32[ 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 (%f)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.F32[ 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,false);
+        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 );
+    psFree(myHist);
+    psFree(myHist2);
+    psFree( tmpImage );
+    psMemCheckCorruption( 1 );
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Calling psImageHistogram() with NULL parameters",
+                 testStatus );
+
+    return ( !testStatus );
+}
Index: /branches/rel4/psLib/test/image/tst_psImageStats01.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageStats01.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageStats01.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psStats * myStats = NULL;
+    psStats *myStats2 = NULL;
+    psImage *tmpImage = NULL;
+    psImage *tmpMask = NULL;
+    psS32 testStatus = true;
+    psS32 memLeaks = 0;
+    psS32 nb = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 IMAGE_X_SIZE = 0;
+    psS32 IMAGE_Y_SIZE = 0;
+    psS32 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,false);
+        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,false);
+    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,false);
+    if( memLeaks != 0 ) {
+        psAbort(__func__, "Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Test With Various Null Inputs",
+                 testStatus );
+    return ( !testStatus );
+}
Index: /branches/rel4/psLib/test/image/tst_psImageStats02.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageStats02.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageStats02.c	(revision 3057)
@@ -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
+psS32 main()
+{
+    psStats * myStats = NULL;
+    psImage *tmpImage = NULL;
+    psImage *outImage = NULL;
+    psImage *nullImage = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    psPolynomial2D *null2DPoly = NULL;
+    psS32 testStatus = true;
+    psS32 memLeaks = 0;
+    psS32 i = 0;
+    psS32 j = 0;
+    psS32 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,false);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Deallocate the psStats/psImage structure.",
+                 testStatus );
+
+    return ( !testStatus );
+}
Index: /branches/rel4/psLib/test/image/tst_psImageStats03.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageStats03.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageStats03.c	(revision 3057)
@@ -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
+
+psS32 main()
+{
+    psImage *tmpImage   = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 j               = 0;
+    float pixel         = 0.0;
+    float x             = 0.0;
+    float y             = 0.0;
+    psS32 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,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel4/psLib/test/image/tst_psImageStats04.c
===================================================================
--- /branches/rel4/psLib/test/image/tst_psImageStats04.c	(revision 3057)
+++ /branches/rel4/psLib/test/image/tst_psImageStats04.c	(revision 3057)
@@ -0,0 +1,185 @@
+/*****************************************************************************
+This routine must ensure that the 
+    psImageFitPolynomial()
+    psImageEvalPolynomial()
+functions work correctly.
+ 
+XXX: We do not check image pixels.
+ *****************************************************************************/
+#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 5
+#define NUM_COLS IMAGE_SIZE
+#define NUM_ROWS IMAGE_SIZE
+#define ERROR_TOL 0.1
+#define A 1.0
+#define B 2.0
+#define C 3.0
+#define D 4.0
+#define E 5.0
+#define F 6.0
+
+#define I_POLY(X, Y) \
+((A) + (B * X) + (C * Y) + (D * X * Y) + (E * X * X) + (F * Y * Y)) \
+
+psS32 FitChebyF32(int numCols, int numRows)
+{
+    psImage *tmpImage     = NULL;
+    psImage *outImage     = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 j               = 0;
+    psS32 currentId       = psMemGetId();
+    float chi2 = 0.0;
+
+
+    printf("psImageFitPolynomial(), psImageEvalPolynom(): (%d by %d)\n", numRows, numCols);
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "psImageFitPolynomial(), psImageEvalPolynom()");
+
+    tmpImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    outImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            tmpImage->data.F32[i][j] = I_POLY(((float) i), ((float) j));
+        }
+    }
+
+    psPolynomial2D *chebys = psPolynomial2DAlloc(5, 5, PS_POLYNOMIAL_CHEB);
+
+    chebys = psImageFitPolynomial(chebys, tmpImage);
+
+    outImage = psImageEvalPolynomial(outImage, chebys);
+
+    chi2 = 0.0;
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            float expect = tmpImage->data.F32[i][j];
+            float actual = outImage->data.F32[i][j];
+            chi2+= (actual-expect) * (actual-expect);
+            if (fabs((actual - expect) / expect) > ERROR_TOL) {
+                printf("pixel [%d][%d] is %.2f should be %.2f\n", i, j, actual, expect);
+            }
+        }
+    }
+    chi2/= ((float) (numCols * numRows));
+    printf("The chi-squared per pixel is %f\n", chi2);
+
+    psFree(tmpImage);
+    psFree(outImage);
+    psFree(chebys);
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psImageStats functions",
+                "psImagePixelInterpolation()",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return(!testStatus);
+}
+
+psS32 FitChebyF64(int numCols, int numRows)
+{
+    psImage *tmpImage     = NULL;
+    psImage *outImage     = NULL;
+    psS32 testStatus      = true;
+    psS32 memLeaks        = 0;
+    psS32 i               = 0;
+    psS32 j               = 0;
+    psS32 currentId       = psMemGetId();
+    double chi2 = 0.0;
+
+
+    printf("psImageFitPolynomial(), psImageEvalPolynom(): (%d by %d)\n", numRows, numCols);
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "psImageFitPolynomial(), psImageEvalPolynom()");
+
+    tmpImage = psImageAlloc(numCols, numRows, PS_TYPE_F64);
+    outImage = psImageAlloc(numCols, numRows, PS_TYPE_F64);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            tmpImage->data.F64[i][j] = I_POLY(((double) i), ((double) j));
+        }
+    }
+
+    psPolynomial2D *chebys = psPolynomial2DAlloc(5, 5, PS_POLYNOMIAL_CHEB);
+
+    chebys = psImageFitPolynomial(chebys, tmpImage);
+
+    outImage = psImageEvalPolynomial(outImage, chebys);
+
+    chi2 = 0.0;
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            double expect = tmpImage->data.F64[i][j];
+            double actual = outImage->data.F64[i][j];
+            chi2+= (actual-expect) * (actual-expect);
+            if (fabs((actual - expect) / expect) > ERROR_TOL) {
+                printf("pixel [%d][%d] is %.2f should be %.2f\n", i, j, actual, expect);
+            }
+        }
+    }
+    chi2/= ((double) (numCols * numRows));
+    printf("The chi-squared per pixel is %f\n", chi2);
+
+    psFree(tmpImage);
+    psFree(outImage);
+    psFree(chebys);
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psImageStats functions",
+                "psImagePixelInterpolation()",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return(!testStatus);
+}
+
+int main()
+{
+    FitChebyF32(1, 1);
+    FitChebyF32(1, NUM_ROWS);
+    FitChebyF32(1, 1);
+    FitChebyF32(NUM_COLS, 1);
+    FitChebyF32(NUM_COLS, NUM_ROWS);
+    FitChebyF64(1, 1);
+    FitChebyF64(1, NUM_ROWS);
+    FitChebyF64(1, 1);
+    FitChebyF64(NUM_COLS, 1);
+    FitChebyF64(NUM_COLS, NUM_ROWS);
+}
Index: /branches/rel4/psLib/test/image/verified/fBiOut.fits
===================================================================
--- /branches/rel4/psLib/test/image/verified/fBiOut.fits	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/fBiOut.fits	(revision 3057)
@@ -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/rel4/psLib/test/image/verified/sBiOut.fits
===================================================================
--- /branches/rel4/psLib/test/image/verified/sBiOut.fits	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/sBiOut.fits	(revision 3057)
@@ -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/rel4/psLib/test/image/verified/tst_psImage.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImage.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImage.stderr	(revision 3057)
@@ -0,0 +1,129 @@
+/***************************** 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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageAlloc (psImage.c:<LINENO>)
+    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|psImageCopy (psImage.c:<LINENO>)
+    Can not operate on a NULL psImage.
+
+---> TESTPOINT PASSED (psImage{psImageCopy} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{psRegionAlloc}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psRegionFromString (psImage.c:<LINENO>)
+    Specified subsection string, '[1:<LINENO>,3:]', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'.
+
+---> TESTPOINT PASSED (psImage{psRegionAlloc} | tst_psImage.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageConvolve.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageConvolve.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageConvolve.stderr	(revision 3057)
@@ -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 an error.
+<DATE><TIME>|<HOST>|E|psKernelGenerate (psImageConvolve.c:<LINENO>)
+    Shift vectors can not be of different sizes.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (time vector NULL).
+<DATE><TIME>|<HOST>|E|psKernelGenerate (psImageConvolve.c:<LINENO>)
+    Specified shift vectors can not be NULL.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (x vector NULL).
+<DATE><TIME>|<HOST>|E|psKernelGenerate (psImageConvolve.c:<LINENO>)
+    Specified shift vectors can not be NULL.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (y vector NULL).
+<DATE><TIME>|<HOST>|E|psKernelGenerate (psImageConvolve.c:<LINENO>)
+    Specified shift vectors can not be NULL.
+
+---> TESTPOINT PASSED (psImage{psKernelGenerate} | tst_psImageConvolve.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageExtraction.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageExtraction.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageExtraction.stderr	(revision 3057)
@@ -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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    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|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|imageSubset (psImageExtraction.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (subsection string is NULL)
+<DATE><TIME>|<HOST>|E|psImageSubsection (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageSlice (psImageExtraction.c:<LINENO>)
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageSlice (psImageExtraction.c:<LINENO>)
+    Specified slice direction, 5, is invalid.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageSlice (psImageExtraction.c:<LINENO>)
+    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|psImageTrim (psImageExtraction.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    Specified subset range, [-1:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    Specified subset range, [0:<LINENO>,-1:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    Specified subset range, [0:-1,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psImageTrim (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageCut (psImageExtraction.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageCut
+    Following should be an error (length=0).
+<DATE><TIME>|<HOST>|E|psImageCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    Specified radii vector can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    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|psImageRadialCut (psImageExtraction.c:<LINENO>)
+    Specified statistic option, 0, is not valid.  Must specify one and only one statistic type.
+
+---> TESTPOINT PASSED (psImage{psImageRadialCut} | tst_psImageExtraction.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageFFT.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 3057)
@@ -0,0 +1,73 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImageFFT}                                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageFFT
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psImageFFT (psImageFFT.c:<LINENO>)
+    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|psImageFFT (psImageFFT.c:<LINENO>)
+    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|psImageFFT (psImageFFT.c:<LINENO>)
+    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|psImageComplex (psImageFFT.c:<LINENO>)
+    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|psImageComplex (psImageFFT.c:<LINENO>)
+    Real psImage size (128x64) and imaginary psImage size (64x64) must be the same.
+<DATE><TIME>|<HOST>|I|testImageComplex
+    Following should generate an error message.
+<DATE><TIME>|<HOST>|E|psImageComplex (psImageFFT.c:<LINENO>)
+    Input psImage type, psS16, is required to be either psF32 or psF64.
+
+---> 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                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImagePowerSpectrum
+    Following should generate error message.
+<DATE><TIME>|<HOST>|E|psImagePowerSpectrum (psImageFFT.c:<LINENO>)
+    Input psImage type, psF32, is required to be either psC32 or psC64.
+
+---> TESTPOINT PASSED (psFFT{psImagePowerSpectrum} | tst_psImageFFT.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageIO.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageIO.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageIO.stderr	(revision 3057)
@@ -0,0 +1,404 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageIO.c                                            *
+*            TestPoint: psImage{psImageReadSection}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as file doesn't exist.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|E|psImageReadSection (psImageIO.c:<LINENO>)
+    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>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|E|psImageReadSection (psImageIO.c:<LINENO>)
+    Specified filename can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as extnum is invalid.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|E|psImageReadSection (psImageIO.c:<LINENO>)
+    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>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|E|psImageReadSection (psImageIO.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should generate an error message because input image is null.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|E|psImageWriteSection (psImageIO.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|E|psImageWriteSection (psImageIO.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|E|psImageWriteSection (psImageIO.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|E|psImageWriteSection (psImageIO.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|E|psImageWriteSection (psImageIO.c:<LINENO>)
+    Specified extension number, 99, must not exceed number of HDUs, 1, by more than one.
+
+---> TESTPOINT PASSED (psImage{psImageWriteSection} | tst_psImageIO.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageInterpolate.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageInterpolate.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageInterpolate.stderr	(revision 3057)
@@ -0,0 +1,48 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageInterpolate.c                                   *
+*            TestPoint: psImagePixelInterpolate{psImagePixelInterpolate}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImagePixelInterpolate{psImagePixelInterpolate} | tst_psImageInterpolate.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageInterpolate.c                                   *
+*            TestPoint: psImagePixelInterpolate{psImagePixelInterpolate}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testInterpolateError
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psImagePixelInterpolate (psImage.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testInterpolateError
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psImagePixelInterpolate (psImage.c:<LINENO>)
+    Specified psImage type, psPtr, is not supported.
+<DATE><TIME>|<HOST>|I|testInterpolateError
+    Following should generate an error message
+<DATE><TIME>|<HOST>|E|psImagePixelInterpolate (psImage.c:<LINENO>)
+    Specified psImage type, psPtr, is not supported.
+
+---> TESTPOINT PASSED (psImagePixelInterpolate{psImagePixelInterpolate} | tst_psImageInterpolate.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageInterpolate.c                                   *
+*            TestPoint: psImagePixelInterpolate{psImagePixelInterpolate}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImagePixelInterpolate{psImagePixelInterpolate} | tst_psImageInterpolate.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageInterpolate.c                                   *
+*            TestPoint: psImagePixelInterpolate{psImagePixelInterpolate}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImagePixelInterpolate{psImagePixelInterpolate} | tst_psImageInterpolate.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageManip.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageManip.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageManip.stderr	(revision 3057)
@@ -0,0 +1,429 @@
+/***************************** 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|psImageClip (psImageManip.c:<LINENO>)
+    Specified min value, 256, can not be greater than the specified max value, 128.
+
+---> 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|psImageClipNaN (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageClipComplexRegion (psImageManip.c:<LINENO>)
+    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|psImageOverlaySection (psImageManip.c:<LINENO>)
+    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|psImageOverlaySection (psImageManip.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as image input is NULL
+<DATE><TIME>|<HOST>|E|psImageOverlaySection (psImageManip.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as operator is invalid
+<DATE><TIME>|<HOST>|E|psImageOverlaySection (psImageManip.c:<LINENO>)
+    Specified operation, '$', is not supported.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as operator is invalid
+<DATE><TIME>|<HOST>|E|psImageOverlaySection (psImageManip.c:<LINENO>)
+    Operation can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as overlay is a different type
+<DATE><TIME>|<HOST>|E|psImageOverlaySection (psImageManip.c:<LINENO>)
+    Input overlay psImage type, psS64, must match input psImage type, psF32.
+
+---> 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|psImageRebin (psImageManip.c:<LINENO>)
+    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|psImageRebin (psImageManip.c:<LINENO>)
+    Input psImage mask type, psF32, is not the supported mask datatype of psU8.
+<DATE><TIME>|<HOST>|E|psImageRebin (psImageManip.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for scale < 0.
+<DATE><TIME>|<HOST>|E|psImageRebin (psImageManip.c:<LINENO>)
+    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|psImageRebin (psImageManip.c:<LINENO>)
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for stats options 0.
+<DATE><TIME>|<HOST>|E|psImageRebin (psImageManip.c:<LINENO>)
+    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|psImageRebin (psImageManip.c:<LINENO>)
+    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|psImageRebin (psImageManip.c:<LINENO>)
+    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|psImageRoll (psImageManip.c:<LINENO>)
+    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>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageWriteSection
+    psImageWriteSection is deprecated.  Consider using psFitsWriteImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|W|psImageReadSection
+    psImageReadSection is deprecated.  Consider using psFitsReadImage instead.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psImageRotate (psImageManip.c:<LINENO>)
+    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|psImageRotate (psImageManip.c:<LINENO>)
+    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|psImageShift (psImageManip.c:<LINENO>)
+    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|psImageShift (psImageManip.c:<LINENO>)
+    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|psImageResample (psImageManip.c:<LINENO>)
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|E|psImageResample (psImageManip.c:<LINENO>)
+    Specified scale value, 0, must be a positive value.
+<DATE><TIME>|<HOST>|E|psImageResample (psImageManip.c:<LINENO>)
+    Specified interpolation mode, 0, is unsupported.
+<DATE><TIME>|<HOST>|E|psImageResample (psImageManip.c:<LINENO>)
+    Specified psImage type, psPtr, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageResample} | tst_psImageManip.c)
+
Index: /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stderr	(revision 3057)
@@ -0,0 +1,10 @@
+<DATE><TIME>|<HOST>|E|psImageHistogram (psImageStats.c:<LINENO>)
+    Unallowable operation: out is NULL.
+<DATE><TIME>|<HOST>|E|psImageHistogram (psImageStats.c:<LINENO>)
+    Unallowable operation: in is NULL.
+<DATE><TIME>|<HOST>|E|psImageHistogram (psImageStats.c:<LINENO>)
+    Unallowable operation: out is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error for invalid mask type.
+<DATE><TIME>|<HOST>|E|psImageHistogram (psImageStats.c:<LINENO>)
+    Unallowable operation: psImage mask has incorrect type.
Index: /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stdout
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 3057)
@@ -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.000000)
+Bin number 1 bounds: (0.1 - 0.2) data (0.000000)
+Bin number 2 bounds: (0.2 - 0.3) data (0.000000)
+Bin number 3 bounds: (0.3 - 0.4) data (0.000000)
+Bin number 4 bounds: (0.4 - 0.5) data (0.000000)
+Bin number 5 bounds: (0.5 - 0.6) data (0.000000)
+Bin number 6 bounds: (0.6 - 0.7) data (0.000000)
+Bin number 7 bounds: (0.7 - 0.8) data (0.000000)
+Bin number 8 bounds: (0.8 - 0.9) data (0.000000)
+Bin number 9 bounds: (0.9 - 1.0) data (0.000000)
+Bin number 10 bounds: (1.0 - 1.1) data (0.000000)
+Bin number 11 bounds: (1.1 - 1.2) data (0.000000)
+Bin number 12 bounds: (1.2 - 1.3) data (0.000000)
+Bin number 13 bounds: (1.3 - 1.4) data (0.000000)
+Bin number 14 bounds: (1.4 - 1.5) data (0.000000)
+Bin number 15 bounds: (1.5 - 1.6) data (0.000000)
+Bin number 16 bounds: (1.6 - 1.7) data (0.000000)
+Bin number 17 bounds: (1.7 - 1.8) data (0.000000)
+Bin number 18 bounds: (1.8 - 1.9) data (0.000000)
+Bin number 19 bounds: (1.9 - 2.0) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (0.10 - 0.20) data (0.000000)
+Bin number 2 bounds: (0.20 - 0.30) data (0.000000)
+Bin number 3 bounds: (0.30 - 0.40) data (0.000000)
+Bin number 4 bounds: (0.40 - 0.50) data (0.000000)
+Bin number 5 bounds: (0.50 - 0.60) data (0.000000)
+Bin number 6 bounds: (0.60 - 0.70) data (0.000000)
+Bin number 7 bounds: (0.70 - 0.80) data (0.000000)
+Bin number 8 bounds: (0.80 - 0.90) data (0.000000)
+Bin number 9 bounds: (0.90 - 1.00) data (0.000000)
+Bin number 10 bounds: (1.00 - 1.10) data (0.000000)
+Bin number 11 bounds: (1.10 - 1.20) data (0.000000)
+Bin number 12 bounds: (1.20 - 1.30) data (0.000000)
+Bin number 13 bounds: (1.30 - 1.40) data (0.000000)
+Bin number 14 bounds: (1.40 - 1.50) data (0.000000)
+Bin number 15 bounds: (1.50 - 1.60) data (0.000000)
+Bin number 16 bounds: (1.60 - 1.70) data (0.000000)
+Bin number 17 bounds: (1.70 - 1.80) data (0.000000)
+Bin number 18 bounds: (1.80 - 1.90) data (0.000000)
+Bin number 19 bounds: (1.90 - 2.00) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (1.7 - 3.3) data (2.000000)
+Bin number 2 bounds: (3.3 - 5.0) data (1.000000)
+Bin number 3 bounds: (5.0 - 6.6) data (2.000000)
+Bin number 4 bounds: (6.6 - 8.2) data (2.000000)
+Bin number 5 bounds: (8.2 - 9.9) data (1.000000)
+Bin number 6 bounds: (9.9 - 11.6) data (2.000000)
+Bin number 7 bounds: (11.6 - 13.2) data (2.000000)
+Bin number 8 bounds: (13.2 - 14.9) data (1.000000)
+Bin number 9 bounds: (14.9 - 16.5) data (2.000000)
+Bin number 10 bounds: (16.5 - 18.2) data (2.000000)
+Bin number 11 bounds: (18.2 - 19.8) data (1.000000)
+Bin number 12 bounds: (19.8 - 21.5) data (2.000000)
+Bin number 13 bounds: (21.5 - 23.1) data (2.000000)
+Bin number 14 bounds: (23.1 - 24.8) data (1.000000)
+Bin number 15 bounds: (24.8 - 26.4) data (2.000000)
+Bin number 16 bounds: (26.4 - 28.1) data (1.000000)
+Bin number 17 bounds: (28.1 - 29.7) data (2.000000)
+Bin number 18 bounds: (29.7 - 31.4) data (2.000000)
+Bin number 19 bounds: (31.4 - 33.0) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (1.65 - 3.30) data (2.000000)
+Bin number 2 bounds: (3.30 - 4.95) data (1.000000)
+Bin number 3 bounds: (4.95 - 6.60) data (2.000000)
+Bin number 4 bounds: (6.60 - 8.25) data (2.000000)
+Bin number 5 bounds: (8.25 - 9.90) data (1.000000)
+Bin number 6 bounds: (9.90 - 11.55) data (2.000000)
+Bin number 7 bounds: (11.55 - 13.20) data (2.000000)
+Bin number 8 bounds: (13.20 - 14.85) data (1.000000)
+Bin number 9 bounds: (14.85 - 16.50) data (2.000000)
+Bin number 10 bounds: (16.50 - 18.15) data (2.000000)
+Bin number 11 bounds: (18.15 - 19.80) data (1.000000)
+Bin number 12 bounds: (19.80 - 21.45) data (2.000000)
+Bin number 13 bounds: (21.45 - 23.10) data (2.000000)
+Bin number 14 bounds: (23.10 - 24.75) data (1.000000)
+Bin number 15 bounds: (24.75 - 26.40) data (2.000000)
+Bin number 16 bounds: (26.40 - 28.05) data (1.000000)
+Bin number 17 bounds: (28.05 - 29.70) data (2.000000)
+Bin number 18 bounds: (29.70 - 31.35) data (2.000000)
+Bin number 19 bounds: (31.35 - 33.00) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (1.7 - 3.3) data (2.000000)
+Bin number 2 bounds: (3.3 - 5.0) data (1.000000)
+Bin number 3 bounds: (5.0 - 6.6) data (2.000000)
+Bin number 4 bounds: (6.6 - 8.2) data (2.000000)
+Bin number 5 bounds: (8.2 - 9.9) data (1.000000)
+Bin number 6 bounds: (9.9 - 11.6) data (2.000000)
+Bin number 7 bounds: (11.6 - 13.2) data (2.000000)
+Bin number 8 bounds: (13.2 - 14.9) data (1.000000)
+Bin number 9 bounds: (14.9 - 16.5) data (2.000000)
+Bin number 10 bounds: (16.5 - 18.2) data (2.000000)
+Bin number 11 bounds: (18.2 - 19.8) data (1.000000)
+Bin number 12 bounds: (19.8 - 21.5) data (2.000000)
+Bin number 13 bounds: (21.5 - 23.1) data (2.000000)
+Bin number 14 bounds: (23.1 - 24.8) data (1.000000)
+Bin number 15 bounds: (24.8 - 26.4) data (2.000000)
+Bin number 16 bounds: (26.4 - 28.1) data (1.000000)
+Bin number 17 bounds: (28.1 - 29.7) data (2.000000)
+Bin number 18 bounds: (29.7 - 31.4) data (2.000000)
+Bin number 19 bounds: (31.4 - 33.0) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (1.65 - 3.30) data (2.000000)
+Bin number 2 bounds: (3.30 - 4.95) data (1.000000)
+Bin number 3 bounds: (4.95 - 6.60) data (2.000000)
+Bin number 4 bounds: (6.60 - 8.25) data (2.000000)
+Bin number 5 bounds: (8.25 - 9.90) data (1.000000)
+Bin number 6 bounds: (9.90 - 11.55) data (2.000000)
+Bin number 7 bounds: (11.55 - 13.20) data (2.000000)
+Bin number 8 bounds: (13.20 - 14.85) data (1.000000)
+Bin number 9 bounds: (14.85 - 16.50) data (2.000000)
+Bin number 10 bounds: (16.50 - 18.15) data (2.000000)
+Bin number 11 bounds: (18.15 - 19.80) data (1.000000)
+Bin number 12 bounds: (19.80 - 21.45) data (2.000000)
+Bin number 13 bounds: (21.45 - 23.10) data (2.000000)
+Bin number 14 bounds: (23.10 - 24.75) data (1.000000)
+Bin number 15 bounds: (24.75 - 26.40) data (2.000000)
+Bin number 16 bounds: (26.40 - 28.05) data (1.000000)
+Bin number 17 bounds: (28.05 - 29.70) data (2.000000)
+Bin number 18 bounds: (29.70 - 31.35) data (2.000000)
+Bin number 19 bounds: (31.35 - 33.00) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (3.2 - 6.4) data (18.000000)
+Bin number 2 bounds: (6.4 - 9.6) data (27.000000)
+Bin number 3 bounds: (9.6 - 12.8) data (36.000000)
+Bin number 4 bounds: (12.8 - 16.0) data (45.000000)
+Bin number 5 bounds: (16.0 - 19.2) data (74.000000)
+Bin number 6 bounds: (19.2 - 22.4) data (66.000000)
+Bin number 7 bounds: (22.4 - 25.6) data (75.000000)
+Bin number 8 bounds: (25.6 - 28.8) data (84.000000)
+Bin number 9 bounds: (28.8 - 32.0) data (93.000000)
+Bin number 10 bounds: (32.0 - 35.2) data (118.000000)
+Bin number 11 bounds: (35.2 - 38.4) data (78.000000)
+Bin number 12 bounds: (38.4 - 41.6) data (69.000000)
+Bin number 13 bounds: (41.6 - 44.8) data (60.000000)
+Bin number 14 bounds: (44.8 - 48.0) data (51.000000)
+Bin number 15 bounds: (48.0 - 51.2) data (54.000000)
+Bin number 16 bounds: (51.2 - 54.4) data (30.000000)
+Bin number 17 bounds: (54.4 - 57.6) data (21.000000)
+Bin number 18 bounds: (57.6 - 60.8) data (12.000000)
+Bin number 19 bounds: (60.8 - 64.0) data (3.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (3.20 - 6.40) data (18.000000)
+Bin number 2 bounds: (6.40 - 9.60) data (27.000000)
+Bin number 3 bounds: (9.60 - 12.80) data (36.000000)
+Bin number 4 bounds: (12.80 - 16.00) data (45.000000)
+Bin number 5 bounds: (16.00 - 19.20) data (74.000000)
+Bin number 6 bounds: (19.20 - 22.40) data (66.000000)
+Bin number 7 bounds: (22.40 - 25.60) data (75.000000)
+Bin number 8 bounds: (25.60 - 28.80) data (84.000000)
+Bin number 9 bounds: (28.80 - 32.00) data (93.000000)
+Bin number 10 bounds: (32.00 - 35.20) data (115.000000)
+Bin number 11 bounds: (35.20 - 38.40) data (66.000000)
+Bin number 12 bounds: (38.40 - 41.60) data (48.000000)
+Bin number 13 bounds: (41.60 - 44.80) data (30.000000)
+Bin number 14 bounds: (44.80 - 48.00) data (12.000000)
+Bin number 15 bounds: (48.00 - 51.20) data (0.000000)
+Bin number 16 bounds: (51.20 - 54.40) data (0.000000)
+Bin number 17 bounds: (54.40 - 57.60) data (0.000000)
+Bin number 18 bounds: (57.60 - 60.80) data (0.000000)
+Bin number 19 bounds: (60.80 - 64.00) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (4.8 - 9.6) data (40.000000)
+Bin number 2 bounds: (9.6 - 14.4) data (65.000000)
+Bin number 3 bounds: (14.4 - 19.2) data (90.000000)
+Bin number 4 bounds: (19.2 - 24.0) data (90.000000)
+Bin number 5 bounds: (24.0 - 28.8) data (135.000000)
+Bin number 6 bounds: (28.8 - 33.6) data (157.000000)
+Bin number 7 bounds: (33.6 - 38.4) data (160.000000)
+Bin number 8 bounds: (38.4 - 43.2) data (160.000000)
+Bin number 9 bounds: (43.2 - 48.0) data (128.000000)
+Bin number 10 bounds: (48.0 - 52.8) data (160.000000)
+Bin number 11 bounds: (52.8 - 57.6) data (160.000000)
+Bin number 12 bounds: (57.6 - 62.4) data (160.000000)
+Bin number 13 bounds: (62.4 - 67.2) data (150.000000)
+Bin number 14 bounds: (67.2 - 72.0) data (102.000000)
+Bin number 15 bounds: (72.0 - 76.8) data (105.000000)
+Bin number 16 bounds: (76.8 - 81.6) data (80.000000)
+Bin number 17 bounds: (81.6 - 86.4) data (55.000000)
+Bin number 18 bounds: (86.4 - 91.2) data (30.000000)
+Bin number 19 bounds: (91.2 - 96.0) data (6.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (4.80 - 9.60) data (40.000000)
+Bin number 2 bounds: (9.60 - 14.40) data (65.000000)
+Bin number 3 bounds: (14.40 - 19.20) data (90.000000)
+Bin number 4 bounds: (19.20 - 24.00) data (90.000000)
+Bin number 5 bounds: (24.00 - 28.80) data (135.000000)
+Bin number 6 bounds: (28.80 - 33.60) data (157.000000)
+Bin number 7 bounds: (33.60 - 38.40) data (160.000000)
+Bin number 8 bounds: (38.40 - 43.20) data (160.000000)
+Bin number 9 bounds: (43.20 - 48.00) data (128.000000)
+Bin number 10 bounds: (48.00 - 52.80) data (154.000000)
+Bin number 11 bounds: (52.80 - 57.60) data (130.000000)
+Bin number 12 bounds: (57.60 - 62.40) data (105.000000)
+Bin number 13 bounds: (62.40 - 67.20) data (76.000000)
+Bin number 14 bounds: (67.20 - 72.00) data (42.000000)
+Bin number 15 bounds: (72.00 - 76.80) data (30.000000)
+Bin number 16 bounds: (76.80 - 81.60) data (6.000000)
+Bin number 17 bounds: (81.60 - 86.40) data (0.000000)
+Bin number 18 bounds: (86.40 - 91.20) data (0.000000)
+Bin number 19 bounds: (91.20 - 96.00) data (0.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (4.8 - 9.6) data (40.000000)
+Bin number 2 bounds: (9.6 - 14.4) data (65.000000)
+Bin number 3 bounds: (14.4 - 19.2) data (90.000000)
+Bin number 4 bounds: (19.2 - 24.0) data (90.000000)
+Bin number 5 bounds: (24.0 - 28.8) data (135.000000)
+Bin number 6 bounds: (28.8 - 33.6) data (157.000000)
+Bin number 7 bounds: (33.6 - 38.4) data (160.000000)
+Bin number 8 bounds: (38.4 - 43.2) data (160.000000)
+Bin number 9 bounds: (43.2 - 48.0) data (128.000000)
+Bin number 10 bounds: (48.0 - 52.8) data (160.000000)
+Bin number 11 bounds: (52.8 - 57.6) data (160.000000)
+Bin number 12 bounds: (57.6 - 62.4) data (160.000000)
+Bin number 13 bounds: (62.4 - 67.2) data (150.000000)
+Bin number 14 bounds: (67.2 - 72.0) data (102.000000)
+Bin number 15 bounds: (72.0 - 76.8) data (105.000000)
+Bin number 16 bounds: (76.8 - 81.6) data (80.000000)
+Bin number 17 bounds: (81.6 - 86.4) data (55.000000)
+Bin number 18 bounds: (86.4 - 91.2) data (30.000000)
+Bin number 19 bounds: (91.2 - 96.0) data (6.000000)
+
+---> 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.000000)
+Bin number 1 bounds: (4.80 - 9.60) data (40.000000)
+Bin number 2 bounds: (9.60 - 14.40) data (65.000000)
+Bin number 3 bounds: (14.40 - 19.20) data (90.000000)
+Bin number 4 bounds: (19.20 - 24.00) data (90.000000)
+Bin number 5 bounds: (24.00 - 28.80) data (135.000000)
+Bin number 6 bounds: (28.80 - 33.60) data (157.000000)
+Bin number 7 bounds: (33.60 - 38.40) data (160.000000)
+Bin number 8 bounds: (38.40 - 43.20) data (160.000000)
+Bin number 9 bounds: (43.20 - 48.00) data (128.000000)
+Bin number 10 bounds: (48.00 - 52.80) data (154.000000)
+Bin number 11 bounds: (52.80 - 57.60) data (130.000000)
+Bin number 12 bounds: (57.60 - 62.40) data (105.000000)
+Bin number 13 bounds: (62.40 - 67.20) data (76.000000)
+Bin number 14 bounds: (67.20 - 72.00) data (42.000000)
+Bin number 15 bounds: (72.00 - 76.80) data (30.000000)
+Bin number 16 bounds: (76.80 - 81.60) data (6.000000)
+Bin number 17 bounds: (81.60 - 86.40) data (0.000000)
+Bin number 18 bounds: (86.40 - 91.20) data (0.000000)
+Bin number 19 bounds: (91.20 - 96.00) data (0.000000)
+
+---> 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/rel4/psLib/test/image/verified/tst_psImageStats01.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats01.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats01.stderr	(revision 3057)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|E|psImageStats (psImageStats.c:<LINENO>)
+    Error: stats->options is 0.
+<DATE><TIME>|<HOST>|E|psImageStats (psImageStats.c:<LINENO>)
+    Unallowable operation: stats is NULL.
+<DATE><TIME>|<HOST>|E|psImageStats (psImageStats.c:<LINENO>)
+    Error: stats->options is 0.
+<DATE><TIME>|<HOST>|E|psImageStats (psImageStats.c:<LINENO>)
+    Unallowable operation: psImage mask has incorrect type.
Index: /branches/rel4/psLib/test/image/verified/tst_psImageStats01.stdout
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/image/verified/tst_psImageStats02.stderr
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats02.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats02.stderr	(revision 3057)
@@ -0,0 +1,16 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message for NULL coeffs argument.
+<DATE><TIME>|<HOST>|E|psImageFitPolynomial (psImageStats.c:<LINENO>)
+    Unallowable operation: polynomial coeffs or its coeffs is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should be a error message for NULL input argument.
+<DATE><TIME>|<HOST>|E|psImageFitPolynomial (psImageStats.c:<LINENO>)
+    Unallowable operation: psImage input or its data is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message for NULL coeffs argument.
+<DATE><TIME>|<HOST>|E|psImageEvalPolynomial (psImageStats.c:<LINENO>)
+    Unallowable operation: polynomial coeffs or its coeffs is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should be a error message for NULL input argument.
+<DATE><TIME>|<HOST>|E|psImageEvalPolynomial (psImageStats.c:<LINENO>)
+    Unallowable operation: psImage input or its data is NULL.
Index: /branches/rel4/psLib/test/image/verified/tst_psImageStats02.stdout
===================================================================
--- /branches/rel4/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 3057)
@@ -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/rel4/psLib/test/psTest.c
===================================================================
--- /branches/rel4/psLib/test/psTest.c	(revision 3057)
+++ /branches/rel4/psLib/test/psTest.c	(revision 3057)
@@ -0,0 +1,249 @@
+//
+// 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"
+
+psBool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,
+                       testDescription tests[], psS32 argc, char * const argv[] )
+{
+    psBool success = true;
+    psBool runAll = true;
+    psBool useFork = true;
+    psBool found;
+    psS32 c;
+    psS32 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 ( psS32 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 ( psS32 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(PS_ERR_UNKNOWN, true, "Failed to parse the testpoint number (%s).",
+                            optarg );
+                    break;
+                }
+                found = false;
+                for ( psS32 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(PS_ERR_UNKNOWN, true, "The specified testpoint number (%d) doesn't exist in this test driver.",
+                            n );
+                    break;
+                }
+                break;
+            case '?':
+                psError(PS_ERR_UNKNOWN, true, "Option %s is not recognized and is ignored.", optarg );
+                break;
+            }
+        }
+    }
+
+    if ( runAll ) {
+        for ( psS32 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( PS_ERR_UNKNOWN, true,
+                 "One or more tests failed" );
+    }
+
+    return success;
+}
+
+psBool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+                  testFcn fcn, psS32 expectedReturn, psBool useFork )
+{
+    psS32 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
+            psS32 currentId = psMemGetId();
+            psS32 retVal = fcn();
+            fflush(stdout);
+            fflush(stderr);
+            if ( retVal == 0 ) { // only bother checking memory if test executed to end.
+                if ( psMemCheckLeaks( currentId, NULL, stderr, false ) != 0 ) {
+                    psError(PS_ERR_UNKNOWN, true, "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 {
+        psS32 currentId = psMemGetId();
+        childReturn = fcn();
+        fflush(stdout);
+        fflush(stderr);
+        if ( childReturn == 0 ) { // only bother checking memory if test executed to end.
+            if ( psMemCheckLeaks( currentId, NULL, stderr, false ) != 0 ) {
+                psError(PS_ERR_UNKNOWN, true, "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,
+                                psS32 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,
+                    psBool 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/rel4/psLib/test/psTest.h
===================================================================
--- /branches/rel4/psLib/test/psTest.h	(revision 3057)
+++ /branches/rel4/psLib/test/psTest.h	(revision 3057)
@@ -0,0 +1,82 @@
+
+#ifndef PSTEST_H
+#define PSTEST_H
+
+#include <stdio.h>
+
+#include "psType.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 psS32 (*testFcn)(void);
+
+typedef struct
+{
+    testFcn     fcn;
+    psS32       testPointNumber;
+    const char* testPointName;
+    psS32       expectedReturn;
+    psBool      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 //////////////////////////////
+
+psBool p_runTest(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    testFcn fcn,
+    psS32 expectedReturn,
+    psBool useFork
+);
+
+psBool p_runTestSuite(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    testDescription tests[],
+    psS32 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,
+    psS32 exitValue
+);
+
+void p_printFooter(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    psBool success
+);
+
+#endif
Index: /branches/rel4/psLib/test/runTest
===================================================================
--- /branches/rel4/psLib/test/runTest	(revision 3057)
+++ /branches/rel4/psLib/test/runTest	(revision 3057)
@@ -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-12-16 21:32:39 $
+#
+#  Copyright 2004 Maui High Performance Computering Center, University of Hawaii
+#
+################################################################################
+
+# Provides functions for handling psS64 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 || $#ARGV < 0) {
+    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/rel4/psLib/test/sysUtils/.cvsignore
===================================================================
--- /branches/rel4/psLib/test/sysUtils/.cvsignore	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/.cvsignore	(revision 3057)
@@ -0,0 +1,12 @@
+temp
+tst_psAbort
+tst_psError
+tst_psLogMsg
+tst_psMemory
+tst_psStringCopy
+tst_psTrace
+tst_psTrace02_OUT
+tst_psTrace
+core*
+log.txt
+tst_psConfigure
Index: /branches/rel4/psLib/test/sysUtils/Makefile
===================================================================
--- /branches/rel4/psLib/test/sysUtils/Makefile	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/Makefile	(revision 3057)
@@ -0,0 +1,50 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.22 $  $Name: not supported by cvs2svn $
+##  $Date: 2005-01-03 23:33:20 $
+##
+##  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      \
+	 tst_psConfigure
+
+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/rel4/psLib/test/sysUtils/tst_psAbort.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psAbort.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psAbort.c	(revision 3057)
@@ -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.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-30 22:00:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+static psS32 testAbort00(void);
+static psS32 testAbort01(void);
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psAbort", tests, argc, argv ) );
+}
+
+static psS32 testAbort00(void)
+{
+    psS32   intval = 1;
+    psS64  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 = %lld 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 psS32 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 psS32 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/rel4/psLib/test/sysUtils/tst_psConfigure.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psConfigure.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psConfigure.c	(revision 3057)
@@ -0,0 +1,52 @@
+/** @file  tst_psConfigure.c
+ *
+ *  @brief Test driver for psconfigure functions
+ *
+ *  This test driver contains the following test points for psConfigure
+ *  functions.
+ *    1) Return current psLib version
+ *
+ *  Return:   Number of test points which failed
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2005-01-03 23:33:20 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+
+static psS32 psLibVersion00(void);
+
+
+testDescription tests[] = {
+                              {psLibVersion00, 0, "Return current psLib version", 0, false},
+                              {NULL}
+                          };
+
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return(!runTestSuite( stderr, "psConfigure", tests, argc, argv));
+}
+
+
+static psS32 psLibVersion00(void)
+{
+    char *stringVal = NULL;
+
+    stringVal = psLibVersion();
+    psLogMsg(__func__,PS_LOG_INFO,"Current psLib version is: %s", stringVal);
+    psFree(stringVal);
+
+
+    return 0;
+}
+
Index: /branches/rel4/psLib/test/sysUtils/tst_psError.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psError.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psError.c	(revision 3057)
@@ -0,0 +1,393 @@
+/** @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.16 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-30 23:44:17 $
+ *
+ *  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 psS32 testError00(void);
+static psS32 testError01(void);
+static psS32 testError02(void);
+static psS32 testError03(void);
+static psS32 testError04(void);
+static psS32 testError05(void);
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( !runTestSuite(stderr, "psError", tests, argc, argv) );
+}
+
+static psS32 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 psS32 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 (psError(code, true, "Error code = %d", code) !=  code) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "Failed return value verify.");
+        return 31;
+    }
+    if (psError((code+1), false, "Error code = %d", (code+1)) != (code+1)) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "Failed return value verify.");
+        return 32;
+    }
+    if (psError((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 psS32 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 (psError(code, true, "Error code = %d", code) !=  code) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "Failed return value verify.");
+        return 23;
+    }
+    if (psError((code+1), false, "Error code = %d", (code+1)) != (code+1)) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "Failed return value verify.");
+        return 24;
+    }
+    if (psError((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 psS32 testError02(void)
+{
+    psErrorCode code = PS_ERR_BAD_PARAMETER_VALUE;
+
+    // Generate error message and verify return value
+    if (psError(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 psS32 testError01(void)
+{
+    psErrorCode code=PS_ERR_BAD_PARAMETER_VALUE;
+
+    // Verify the return value of psErrorMsg is the psErrorCode passed
+    if ( psError(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 ( psError(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");
+
+    // test1D undefined code
+    if ( psError(-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( psError(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( psError(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 psS32 testError00(void)
+{
+
+    psS32  intval=1;
+    psS64 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(PS_ERR_UNKNOWN, true,
+            "ALL TYPES intval = %d longval = %lld floatval = %f charval = %c strval = %s",
+            intval,longval,floatval,charval,stringval);
+
+    // Test point #2 String values in error message
+    psError(PS_ERR_UNKNOWN, true, "NO VALUES");
+
+    // Test point #3 Empty strings in error message
+    psError(PS_ERR_UNKNOWN, true, "");
+
+    return 0;
+}
+
+static psS32 testErrorRegister(void)
+{
+
+    psS32 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 (psS32 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/rel4/psLib/test/sysUtils/tst_psLogMsg.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psLogMsg.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psLogMsg.c	(revision 3057)
@@ -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 psS32 testLogMsg00();
+static psS32 testLogMsg01();
+static psS32 testLogMsg02();
+static psS32 testLogMsg03();
+static psS32 testLogMsg04();
+static psS32 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
+                              }
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psLogMsg", tests, argc, argv ) );
+}
+
+
+static void myLogMsg(const char *name,
+                     psS32 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 psS32 testLogMsg00()
+{
+    psS32 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 psS32 testLogMsg01()
+{
+    psS32 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 psS32 testLogMsg02()
+{
+
+    psLogSetLevel(9);
+    // Send a log messages for levels 0:9.
+    for (psS32 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 psS32 testLogMsg03()
+{
+    psS32 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;
+}
+
+
+psS32 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;
+}
+
+psS32 testLogMsg05()
+{
+    psS32 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/rel4/psLib/test/sysUtils/tst_psMemory.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psMemory.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psMemory.c	(revision 3057)
@@ -0,0 +1,537 @@
+/** @file  tst_psMemory.c
+*
+*  @brief Contains the tests for psMemory.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-12-13 20:49:56 $
+*
+*  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 psS32 TPFreeReferencedMemory( void );
+static psS32 TPOutOfMemory( void );
+static psS32 TPReallocOutOfMemory( void );
+static psPtr TPOutOfMemoryExhaustedCallback( size_t size );
+static psS32 TPCheckBufferPositive( void );
+static psS32 TPrealloc( void );
+static psS32 TPallocCallback( void );
+static psMemoryId memAllocateCallback( const psMemBlock *ptr );
+static psMemoryId memFreeCallback( const psMemBlock *ptr );
+static psS32 TPcheckLeaks( void );
+static psS32 TPmemCorruption( void );
+static psS32 TPmultipleFree( void );
+void memProblemCallback( const psMemBlock *ptr, const char *file, psS32 lineno );
+
+static psS32 problemCallbackCalled = 0;
+static psS32 allocCallbackCalled = 0;
+static psS32 freeCallbackCalled = 0;
+static psS32 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", -6, false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psMemory", tests, argc, argv ) );
+}
+
+// Testpoint #449, psAlloc shall allocate memory blocks writeable by caller.
+psS32 TPCheckBufferPositive( void )
+{
+    psS32 * mem;
+    const psS32 size = 100;
+    psS32 failed = 0;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psAlloc shall allocate memory blocks writeable by caller.\n" );
+
+    mem = ( psS32* ) psAlloc( size * sizeof( psS32 ) );
+    if ( mem == NULL ) {
+        psError(PS_ERR_UNKNOWN, true, "psAlloc returned a NULL value in %s!", __func__ );
+        return 1;
+    }
+
+    for ( psS32 index = 0;index < size;index++ ) {
+        mem[ index ] = index;
+    }
+
+    for ( psS32 index = 0;index < size;index++ ) {
+        if ( mem[ index ] != index ) {
+            failed++;
+        }
+    }
+
+    psFree( mem );
+
+    return failed;
+}
+
+psS32 TPFreeReferencedMemory( void )
+{
+    // create memory
+    psS32 * mem;
+    psS32 ref = 0;
+
+    psLogMsg( __func__, PS_LOG_INFO, "memory reference count shall be incrementable/decrementable" );
+
+    mem = ( psS32* ) psAlloc( 100 * sizeof( psS32 ) );
+
+    ref = psMemGetRefCounter( mem );
+    if ( ref != 1 ) {
+        psError(PS_ERR_UNKNOWN, true, "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(PS_ERR_UNKNOWN, true, "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(PS_ERR_UNKNOWN, true, "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(PS_ERR_UNKNOWN, true, "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.
+psS32 TPReallocOutOfMemory( void )
+{
+    psS32 * mem[ 100 ];
+    psMemExhaustedCallback cb;
+
+    for ( psS32 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 ( psS32 lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( psS32* ) psAlloc( 10 );
+    }
+
+    for ( psS32 lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( psS32* ) psRealloc( mem[ lcv ], SIZE_MAX/2 - 1000 );
+    }
+
+    psMemExhaustedCallbackSet( cb );
+
+    if ( exhaustedCallbackCalled == 0 ) {
+        psError(PS_ERR_UNKNOWN,true, "Called psRealloc with HUGE memory requirement and survived in %s!", __func__ );
+        return 1;
+    }
+
+    for ( psS32 lcv = 0; lcv < 100; lcv++ ) {
+        psFree( mem[ lcv ] );
+    }
+
+    return 0;
+}
+// Testpoint #450,  Upon requesting more memory than is available, psalloc shall call
+// the psMemExhaustedCallback.
+psS32 TPOutOfMemory( void )
+{
+    psS32 * mem[ 100 ];
+    psMemExhaustedCallback cb;
+
+    for ( psS32 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 ( psS32 lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( psS32* ) psAlloc( SIZE_MAX/2 - 1000 );
+    }
+
+    psMemExhaustedCallbackSet( cb );
+
+    if ( exhaustedCallbackCalled == 0 ) {
+        psError(PS_ERR_UNKNOWN,true, "Called psAlloc with HUGE memory requirement and survived in %s!", __func__ );
+        return 1;
+    }
+
+    for ( psS32 lcv = 0; lcv < 100; lcv++ ) {
+        psFree( mem[ lcv ] );
+    }
+
+    return 0;
+}
+
+// Testpoint #451,  psRealloc shall increase/decrease memory buffer while preserving contents
+psS32 TPrealloc( void )
+{
+    psS32 * mem1;
+    psS32* mem2;
+    psS32* mem3;
+    const psS32 initialSize = 100;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psRealloc shall increase/decrease memory buffer while "
+              "preserving contents" );
+
+    // allocate buffer with known values.
+    mem1 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+    mem2 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+    mem3 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+    for ( psS32 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 = ( psS32* ) psRealloc( mem1, 2 * initialSize * sizeof( psS32 ) );
+    mem2 = ( psS32* ) psRealloc( mem2, 2 * initialSize * sizeof( psS32 ) );
+    mem3 = ( psS32* ) psRealloc( mem3, 2 * initialSize * sizeof( psS32 ) );
+
+    // check values of initial block
+    for ( psS32 i = 0;i < initialSize;i++ ) {
+        if ( mem1[ i ] != i || mem2[ i ] != i || mem3[ i ] != i ) {
+            psError(PS_ERR_UNKNOWN,true, "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 = ( psS32* ) psRealloc( mem1, ( initialSize / 2 ) * sizeof( psS32 ) );
+    mem2 = ( psS32* ) psRealloc( mem2, ( initialSize / 2 ) * sizeof( psS32 ) );
+    mem3 = ( psS32* ) psRealloc( mem3, ( initialSize / 2 ) * sizeof( psS32 ) );
+
+    // check values of initial block
+    for ( psS32 i = 0;i < initialSize / 2;i++ ) {
+        if ( mem1[ i ] != i || mem2[ i ] != i || mem3[ i ] != i ) {
+            psError(PS_ERR_UNKNOWN,true, "Realloc didn't preserve the contents with shrinking buffer in %s.",
+                    __func__ );
+            break;
+        }
+    }
+
+    psFree( mem1 );
+    psFree( mem2 );
+    psFree( mem3 );
+
+    return 0;
+}
+
+psS32 TPallocCallback( void )
+{
+    psS32 * mem1;
+    psS32* mem2;
+    psS32* mem3;
+    psS32 currentId = psMemGetId();
+    const psS32 initialSize = 100;
+    psS32 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 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+    mem2 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+    mem3 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+
+    psFree( mem1 );
+    psFree( mem2 );
+    psFree( mem3 );
+
+    if ( allocCallbackCalled != 2 || freeCallbackCalled != 2 ) {
+        psError(PS_ERR_UNKNOWN,true, "alloc/free callbacks were not called the proper number of times in %s",
+                __func__ );
+        return 1;
+    }
+
+    allocCallbackCalled = 0;
+    freeCallbackCalled = 0;
+
+    mark = psMemGetId();
+
+    mem1 = ( psS32* ) psAlloc( initialSize * sizeof( psS32 ) );
+
+    psMemAllocateCallbackSetID( mark );
+
+    mem1 = ( psS32* ) psRealloc( mem1, initialSize * 2 * sizeof( psS32 ) );
+
+    psFree( mem1 );
+
+    if ( allocCallbackCalled != 2 ) {
+        psError(PS_ERR_UNKNOWN,true, "realloc callbacks were not called the proper number of times in %s",
+                __func__ );
+        return 1;
+    }
+
+    return 0;
+
+}
+
+psS32 TPcheckLeaks( void )
+{
+    const psS32 numBuffers = 5;
+    psS32* buffers[ 5 ];
+    psS32 lcv;
+    psS32 currentId = psMemGetId();
+    psMemBlock** blks;
+    psS32 nLeaks = 0;
+    psS32 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( psS32 ) );
+    }
+
+    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, false );
+
+    if ( nLeaks != 1 ) {
+        psError(PS_ERR_UNKNOWN,true, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError(PS_ERR_UNKNOWN,true, "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, false);
+
+    for ( lcv = 0;lcv < numBuffers;lcv++ ) {
+        lineMark = __LINE__ + 1;
+        buffers[ lcv ] = psAlloc( sizeof( psS32 ) );
+    }
+
+    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, false );
+
+    if ( nLeaks != 1 ) {
+        psError(PS_ERR_UNKNOWN,true, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError(PS_ERR_UNKNOWN,true, "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( psS32 ) );
+    }
+
+    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, false );
+
+    if ( nLeaks != 2 ) {
+        psError(PS_ERR_UNKNOWN,true, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError(PS_ERR_UNKNOWN,true, "psMemCheckLeaks found a leak other than the expected one in %s.", __func__ );
+        return 1;
+    }
+
+    psFree( blks );
+    psFree( buffers[ 1 ] );
+    psFree( buffers[ 3 ] );
+
+    return 0;
+}
+
+psS32 TPmemCorruption( void )
+{
+    psS32 * buffer = NULL;
+    psS32 oldValue = 0;
+    psS32 corruptions = 0;
+    psMemProblemCallback cb;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psMemCheckCorruption shall detect memory corruptions" );
+
+    buffer = psAlloc( sizeof( psS32 ) );
+
+    // 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(PS_ERR_UNKNOWN,true, "Expected one memory corruption but found %d in %s.",
+                corruptions, __func__ );
+        return 1;
+    }
+
+    if ( problemCallbackCalled != 1 ) {
+        psError(PS_ERR_UNKNOWN,true, "The memProblemCallback was not invoked but should have been in %s",
+                __func__ );
+        return 1;
+    }
+
+    return 0;
+
+}
+
+void memProblemCallback( const psMemBlock *ptr, const char *file, psS32 lineno )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "memory callback called for id %lld (%s:%d).",
+              ptr->id, file, lineno );
+    problemCallbackCalled++;
+    return ;
+}
+
+psMemoryId memAllocateCallback( const psMemBlock *ptr )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "block %lld was (re)allocated", ptr->id );
+    allocCallbackCalled++;
+    return 1;
+}
+
+psMemoryId memFreeCallback( const psMemBlock *ptr )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "block %lld was freed", ptr->id );
+    freeCallbackCalled++;
+    return 1;
+}
+
+psPtr TPOutOfMemoryExhaustedCallback( size_t size )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "Custom MemExhaustedCallback was invoked." );
+    exhaustedCallbackCalled++;
+    return NULL;
+}
+
+psS32 TPmultipleFree( void )
+{
+
+    psPtr  buffer = psAlloc( 1024 );
+
+    psFree( buffer );
+
+    psLogMsg( __func__, PS_LOG_INFO, "Next should abort due to multiple freeing." );
+    psFree( buffer );
+
+    psError(PS_ERR_UNKNOWN,true,
+            "Multiple psFree call survived");
+
+    return 0;
+}
Index: /branches/rel4/psLib/test/sysUtils/tst_psString.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psString.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psString.c	(revision 3057)
@@ -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.11 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-04 19:30:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static psS32 testStringCopy00(void);
+static psS32 testStringCopy01(void);
+static psS32 testStringCopy02(void);
+static psS32 testStringCopy03(void);
+static psS32 testStringCopy04(void);
+static psS32 testStringCopy05(void);
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psString", tests, argc, argv ) );
+}
+
+/*
+psS32 main( psS32 argc,
+          char * argv[] )
+{
+    psBool  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";
+    psS32   substringlen = 6;
+    char  *emptyval = "";
+    psS32   tpFails = 0;
+    char  *strResult;
+    psS32   increaseSize = 5;
+    psS32   negativeSize = -5;
+    psS32   result = 0;
+    psS32   result1 = 0;
+    psS32   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+ 
+*/
+
+static psS32 testStringCopy00(void)
+{
+    char  stringval[20] = "E R R O R";
+    psS32   result = 0;
+    psS32   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 psS32 testStringCopy01(void)
+{
+    char  *emptyval = "";
+    psS32   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 psS32 testStringCopy02(void)
+{
+    psS32   result = 0;
+    psS32   result1 = 0;
+    char  *strResult;
+    char  stringval1[20] = "e r r o r";
+    psS32   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 psS32 testStringCopy03(void)
+{
+    psS32   result = 0;
+    psS32   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 psS32 testStringCopy04(void)
+{
+    psS32   result = 0;
+    psS32   result1 = 0;
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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,
+                (psS32)strlen(stringval));
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static psS32 testStringCopy05(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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 = %p expected NULL\n",
+                strResult);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
+
+static psS32 testStringCopy06(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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/rel4/psLib/test/sysUtils/tst_psStringCopy.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psStringCopy.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psStringCopy.c	(revision 3057)
@@ -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.11 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-11-04 19:30:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static psS32 testStringCopy00(void);
+static psS32 testStringCopy01(void);
+static psS32 testStringCopy02(void);
+static psS32 testStringCopy03(void);
+static psS32 testStringCopy04(void);
+static psS32 testStringCopy05(void);
+static psS32 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}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psString", tests, argc, argv ) );
+}
+
+/*
+psS32 main( psS32 argc,
+          char * argv[] )
+{
+    psBool  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";
+    psS32   substringlen = 6;
+    char  *emptyval = "";
+    psS32   tpFails = 0;
+    char  *strResult;
+    psS32   increaseSize = 5;
+    psS32   negativeSize = -5;
+    psS32   result = 0;
+    psS32   result1 = 0;
+    psS32   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+ 
+*/
+
+static psS32 testStringCopy00(void)
+{
+    char  stringval[20] = "E R R O R";
+    psS32   result = 0;
+    psS32   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 psS32 testStringCopy01(void)
+{
+    char  *emptyval = "";
+    psS32   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 psS32 testStringCopy02(void)
+{
+    psS32   result = 0;
+    psS32   result1 = 0;
+    char  *strResult;
+    char  stringval1[20] = "e r r o r";
+    psS32   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 psS32 testStringCopy03(void)
+{
+    psS32   result = 0;
+    psS32   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 psS32 testStringCopy04(void)
+{
+    psS32   result = 0;
+    psS32   result1 = 0;
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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,
+                (psS32)strlen(stringval));
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static psS32 testStringCopy05(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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 = %p expected NULL\n",
+                strResult);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
+
+static psS32 testStringCopy06(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    psS32   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/rel4/psLib/test/sysUtils/tst_psTrace.c
===================================================================
--- /branches/rel4/psLib/test/sysUtils/tst_psTrace.c	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/tst_psTrace.c	(revision 3057)
@@ -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 psS32 testTrace00(void);
+static psS32 testTrace01(void);
+static psS32 testTrace02(void);
+static psS32 testTrace03(void);
+static psS32 testTrace04(void);
+static psS32 testTrace05(void);
+static psS32 testTrace05a(void);
+static psS32 testTrace06(void);
+static psS32 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/dynamic 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},
+                           };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psTrace", tests, argc, argv ) );
+}
+
+static psS32 testTrace00(void)
+{
+    psS32 i;
+    psS32 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 psS32 testTrace01(void)
+{
+    psTraceSetDestination(stderr);
+    (void)psTraceSetLevel(".A.B.C.D.E", 5);
+
+    psTracePrintLevels();
+
+    return 0;
+}
+
+static psS32 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 psS32 testTrace03(void)
+{
+    psS32 i = 0;
+    psS32 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 psS32 testTrace04(void)
+{
+    FILE *fp;
+    psS32 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 psS32 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 psS32 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 psS32 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 psS32 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/rel4/psLib/test/sysUtils/verified/tst_psAbort.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psAbort.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psAbort.stderr	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psConfigure.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psConfigure.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psConfigure.stderr	(revision 3057)
@@ -0,0 +1,11 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psConfigure.c                                          *
+*            TestPoint: psConfigure{Return current psLib version}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|psLibVersion00
+    Current psLib version is: rel4
+
+---> TESTPOINT PASSED (psConfigure{Return current psLib version} | tst_psConfigure.c)
+
Index: /branches/rel4/psLib/test/sysUtils/verified/tst_psError.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 3057)
@@ -0,0 +1,112 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psError()}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|testError00 (tst_psError.c:<LINENO>)
+    ALL TYPES intval = 1 longval = 2 floatval = 3.010000 charval = E strval = E R R O R
+<DATE><TIME>|<HOST>|E|testError00 (tst_psError.c:<LINENO>)
+    NO VALUES
+<DATE><TIME>|<HOST>|E|testError00 (tst_psError.c:<LINENO>)
+
+---> TESTPOINT PASSED (psError{psError()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorMsg(),psErrorStackPrint()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|testError01 (tst_psError.c:<LINENO>)
+    Error code = 262
+ERROR STACK PRINT Test1A -> testError01 (tst_psError.c:<LINENO>): parameter is out-of-range
+     Error code = 262
+<DATE><TIME>|<HOST>|E|testError01 (tst_psError.c:<LINENO>)
+    Error code = 263
+ERROR STACK PRINT Test1B -> testError01 (tst_psError.c:<LINENO>): parameter is of unsupported type
+     Error code = 263
+<DATE><TIME>|<HOST>|E|testError01 (tst_psError.c:<LINENO>)
+    Error code = -1
+ERROR STACK PRINT Test1D -> testError01 (tst_psError.c:<LINENO>): (null)
+     Error code = -1
+<DATE><TIME>|<HOST>|E|testError01 (tst_psError.c:<LINENO>)
+    Error code = 262
+ERROR STACK PRINT Test1E -> testError01 (tst_psError.c:<LINENO>): (null)
+     Error code = -1
+ -> testError01 (tst_psError.c:<LINENO>): parameter is out-of-range
+     Error code = 262
+<DATE><TIME>|<HOST>|E|testError01 (tst_psError.c:<LINENO>)
+    Errno code = 9
+ERROR STACK PRINT Test1F -> testError01 (tst_psError.c:<LINENO>): 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|testError02 (tst_psError.c:<LINENO>)
+    Error code = 262
+ERROR STACK PRINT Test2A -> testError02 (tst_psError.c:<LINENO>): 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|testError03 (tst_psError.c:<LINENO>)
+    Error code = 262
+<DATE><TIME>|<HOST>|E|testError03 (tst_psError.c:<LINENO>)
+    Error code = 263
+<DATE><TIME>|<HOST>|E|testError03 (tst_psError.c:<LINENO>)
+    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|testError04 (tst_psError.c:<LINENO>)
+    Error code = 262
+<DATE><TIME>|<HOST>|E|testError04 (tst_psError.c:<LINENO>)
+    Error code = 263
+<DATE><TIME>|<HOST>|E|testError04 (tst_psError.c:<LINENO>)
+    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|psErrorRegister (psErrorCodes.c:<LINENO>)
+    Specified psErrorDescription pointer can not be NULL.
+
+---> TESTPOINT PASSED (psError{psErrorRegister()} | tst_psError.c)
+
Index: /branches/rel4/psLib/test/sysUtils/verified/tst_psHash00.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psHash01.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psHash03.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psHash04.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stderr	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psLogMsg.stdout	(revision 3057)
@@ -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/rel4/psLib/test/sysUtils/verified/tst_psMemory.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 3057)
@@ -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|checkMemBlock (psMemory.c:<LINENO>)
+    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 abort due to multiple freeing.
+<DATE><TIME>|<HOST>|A|p_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/rel4/psLib/test/sysUtils/verified/tst_psStringCopy.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 3057)
@@ -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|psStringNCopy (psString.c:<LINENO>)
+    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/rel4/psLib/test/sysUtils/verified/tst_psTrace.stderr
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psTrace.stderr	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psTrace.stderr	(revision 3057)
@@ -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                                                   *
+\**********************************************************************************/
+
+.                    0
+ A                   0
+  B                  0
+   C                 0
+    D                0
+     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/dynamic inheritance} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+.                    0
+ A                   0
+  B                  2
+   C                 2
+    D                2
+     E               5
+.                    0
+ A                   0
+  B                  10
+   C                 10
+    D                10
+     E               5
+
+---> TESTPOINT PASSED (psTrace{psTraceSetLevel(): test static/dynamic 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/rel4/psLib/test/sysUtils/verified/tst_psTrace.stdout
===================================================================
--- /branches/rel4/psLib/test/sysUtils/verified/tst_psTrace.stdout	(revision 3057)
+++ /branches/rel4/psLib/test/sysUtils/verified/tst_psTrace.stdout	(revision 3057)
@@ -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/rel4/psLib/test/tst_template.c
===================================================================
--- /branches/rel4/psLib/test/tst_template.c	(revision 3057)
+++ /branches/rel4/psLib/test/tst_template.c	(revision 3057)
@@ -0,0 +1,92 @@
+/** @file  tst_psImageManip.c
+*
+*  @brief Contains the tests for psImageManip.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-27 00:57:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static psS32 test1( void );
+static psS32 test2( void );
+static psS32 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
+                              }
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+psS32 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
+}
+
+psS32 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
+}
+
+psS32 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/rel4/psModules/.cvsignore
===================================================================
--- /branches/rel4/psModules/.cvsignore	(revision 3057)
+++ /branches/rel4/psModules/.cvsignore	(revision 3057)
@@ -0,0 +1,5 @@
+autom4te.cache
+Makefile
+config.log
+config.status
+libtool
Index: /branches/rel4/psModules/AUTHORS
===================================================================
--- /branches/rel4/psModules/AUTHORS	(revision 3057)
+++ /branches/rel4/psModules/AUTHORS	(revision 3057)
@@ -0,0 +1,1 @@
+Maui High Performance Computing Center, University of Hawai'i
Index: /branches/rel4/psModules/COPYING
===================================================================
--- /branches/rel4/psModules/COPYING	(revision 3057)
+++ /branches/rel4/psModules/COPYING	(revision 3057)
@@ -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/rel4/psModules/ChangeLog
===================================================================
--- /branches/rel4/psModules/ChangeLog	(revision 3057)
+++ /branches/rel4/psModules/ChangeLog	(revision 3057)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel4/psModules/INSTALL
===================================================================
--- /branches/rel4/psModules/INSTALL	(revision 3057)
+++ /branches/rel4/psModules/INSTALL	(revision 3057)
@@ -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/rel4/psModules/Makefile.am
===================================================================
--- /branches/rel4/psModules/Makefile.am	(revision 3057)
+++ /branches/rel4/psModules/Makefile.am	(revision 3057)
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign 1.4
+
+SUBDIRS = src test
Index: /branches/rel4/psModules/Makefile.cvs
===================================================================
--- /branches/rel4/psModules/Makefile.cvs	(revision 3057)
+++ /branches/rel4/psModules/Makefile.cvs	(revision 3057)
@@ -0,0 +1,8 @@
+default: all
+
+all:
+	aclocal
+	autoheader
+	automake
+	autoconf
+
Index: /branches/rel4/psModules/Makefile.in
===================================================================
--- /branches/rel4/psModules/Makefile.in	(revision 3057)
+++ /branches/rel4/psModules/Makefile.in	(revision 3057)
@@ -0,0 +1,579 @@
+# Makefile.in generated by automake 1.9.2 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 = :
+build_triplet = @build@
+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@
+am__tar = @am__tar@
+am__untar = @am__untar@
+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; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	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; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+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='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(mkdir_p) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	    distdir=`$(am__cd) $(distdir) && pwd`; \
+	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+	    (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
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | 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
+	tardir=$(distdir) && $(am__tar) | 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 | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.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:
+	-test -z "$(CONFIG_CLEAN_FILES)" || 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/rel4/psModules/NEWS
===================================================================
--- /branches/rel4/psModules/NEWS	(revision 3057)
+++ /branches/rel4/psModules/NEWS	(revision 3057)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel4/psModules/README
===================================================================
--- /branches/rel4/psModules/README	(revision 3057)
+++ /branches/rel4/psModules/README	(revision 3057)
@@ -0,0 +1,1 @@
+
Index: /branches/rel4/psModules/TODO
===================================================================
--- /branches/rel4/psModules/TODO	(revision 3057)
+++ /branches/rel4/psModules/TODO	(revision 3057)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel4/psModules/aclocal.m4
===================================================================
--- /branches/rel4/psModules/aclocal.m4	(revision 3057)
+++ /branches/rel4/psModules/aclocal.m4	(revision 3057)
@@ -0,0 +1,6969 @@
+# generated automatically by aclocal 1.9.2 -*- 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.9"])
+
+# 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.9.2])])
+
+# 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, 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 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
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' 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
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  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 "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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, 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 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.58])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_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([tar-ustar], [_AM_PROG_TAR([ustar])],
+              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+	      		     [_AM_PROG_TAR([v7])])])
+_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
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  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])])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 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 1
+
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
Index: /branches/rel4/psModules/config.guess
===================================================================
--- /branches/rel4/psModules/config.guess	(revision 3057)
+++ /branches/rel4/psModules/config.guess	(revision 3057)
@@ -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/rel4/psModules/config.sub
===================================================================
--- /branches/rel4/psModules/config.sub	(revision 3057)
+++ /branches/rel4/psModules/config.sub	(revision 3057)
@@ -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/rel4/psModules/configure
===================================================================
--- /branches/rel4/psModules/configure	(revision 3057)
+++ /branches/rel4/psModules/configure	(revision 3057)
@@ -0,0 +1,21289 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 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
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/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 -z "`(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
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval 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="eval 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 install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar 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
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    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 (C) 2003 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.59.  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 &&
+  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.9"
+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"
+# OS/2's system install, which has a completely different semantic
+# ./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/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /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
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  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"}
+
+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.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+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
+/* 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 file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $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
+/* 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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 \
+   '' \
+   '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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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.err 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
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' 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"
+# OS/2's system install, which has a completely different semantic
+# ./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/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /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 3745 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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
+/* 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
+/* 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 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_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:$ac_c_preproc_warn_flag 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 compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  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: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&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;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 \
+   '' \
+   '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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' 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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_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
+/* 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
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_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 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+  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 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+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:5317:" \
+     "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); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+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>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); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+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>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); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
+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:6351: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6355: \$? = $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:6584: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6588: \$? = $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:6644: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:6648: \$? = $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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 7978 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* 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
+
+#undef shl_load
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* 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
+
+#undef dlopen
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 8849 "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 8947 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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:11126: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:11130: \$? = $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:11186: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:11190: \$? = $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 11697 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* 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
+
+#undef shl_load
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* 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
+
+#undef dlopen
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 12568 "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 12666 "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:13493: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:13497: \$? = $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:13553: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13557: \$? = $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>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); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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>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); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 14867 "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:15608: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15612: \$? = $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:15841: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15845: \$? = $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:15901: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:15905: \$? = $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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 17235 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* 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
+
+#undef shl_load
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* 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
+
+#undef dlopen
+
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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 18106 "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 18204 "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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+/* 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>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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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.err 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
+
+
+
+echo "$as_me:$LINENO: checking for sqrtf in -lmx" >&5
+echo $ECHO_N "checking for sqrtf in -lmx... $ECHO_C" >&6
+if test "${ac_cv_lib_mx_sqrtf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmx  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* 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 sqrtf ();
+int
+main ()
+{
+sqrtf ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 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); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (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); }; } &&
+	 { 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_mx_sqrtf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mx_sqrtf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mx_sqrtf" >&5
+echo "${ECHO_T}$ac_cv_lib_mx_sqrtf" >&6
+if test $ac_cv_lib_mx_sqrtf = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMX 1
+_ACEOF
+
+  LIBS="-lmx $LIBS"
+
+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
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/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 -z "`(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
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval 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="eval 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.59.  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.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 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,@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,@AMTAR@,$AMTAR,;t t
+s,@am__tar@,$am__tar,;t t
+s,@am__untar@,$am__untar,;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
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  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; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 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'`
+  { 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
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  { 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
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  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 "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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/rel4/psModules/configure.in
===================================================================
--- /branches/rel4/psModules/configure.in	(revision 3057)
+++ /branches/rel4/psModules/configure.in	(revision 3057)
@@ -0,0 +1,69 @@
+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))
+
+dnl for MacOSX, where sqrtf is in mx
+AC_CHECK_LIB(mx,sqrtf)
+
+AC_OUTPUT(Makefile src/Makefile test/Makefile)
Index: /branches/rel4/psModules/depcomp
===================================================================
--- /branches/rel4/psModules/depcomp	(revision 3057)
+++ /branches/rel4/psModules/depcomp	(revision 3057)
@@ -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/rel4/psModules/install-sh
===================================================================
--- /branches/rel4/psModules/install-sh	(revision 3057)
+++ /branches/rel4/psModules/install-sh	(revision 3057)
@@ -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/rel4/psModules/ltmain.sh
===================================================================
--- /branches/rel4/psModules/ltmain.sh	(revision 3057)
+++ /branches/rel4/psModules/ltmain.sh	(revision 3057)
@@ -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/rel4/psModules/missing
===================================================================
--- /branches/rel4/psModules/missing	(revision 3057)
+++ /branches/rel4/psModules/missing	(revision 3057)
@@ -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/rel4/psModules/mkinstalldirs
===================================================================
--- /branches/rel4/psModules/mkinstalldirs	(revision 3057)
+++ /branches/rel4/psModules/mkinstalldirs	(revision 3057)
@@ -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/rel4/psModules/psmodule.kdevelop
===================================================================
--- /branches/rel4/psModules/psmodule.kdevelop	(revision 3057)
+++ /branches/rel4/psModules/psmodule.kdevelop	(revision 3057)
@@ -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/rel4/psModules/psmodule.kdevses
===================================================================
--- /branches/rel4/psModules/psmodule.kdevses	(revision 3057)
+++ /branches/rel4/psModules/psmodule.kdevses	(revision 3057)
@@ -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/rel4/psModules/src/.cvsignore
===================================================================
--- /branches/rel4/psModules/src/.cvsignore	(revision 3057)
+++ /branches/rel4/psModules/src/.cvsignore	(revision 3057)
@@ -0,0 +1,4 @@
+.deps
+Makefile
+config.h
+stamp-h1
Index: /branches/rel4/psModules/src/Doxyfile
===================================================================
--- /branches/rel4/psModules/src/Doxyfile	(revision 3057)
+++ /branches/rel4/psModules/src/Doxyfile	(revision 3057)
@@ -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.1-R4
+
+# 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/rel4/psModules/src/Makefile.am
===================================================================
--- /branches/rel4/psModules/src/Makefile.am	(revision 3057)
+++ /branches/rel4/psModules/src/Makefile.am	(revision 3057)
@@ -0,0 +1,7 @@
+lib_LIBRARIES = libpsmodule.a
+
+libpsmodule_a_SOURCES = pmFlatField.c pmMaskBadPixels.c pmSubtractBias.c psTest.c pmSubtractBias.c pmNonLinear.c pmReadoutCombine.c pmSubtractSky.c
+
+libpsmodule_a_HEADERS = pmFlatField.h pmMaskBadPixels.h pmSubtractBias.h psTest.h pmSubtractBias.h pmNonLinear.h pmReadoutCombine.h pmSubtractSky.h
+
+libpsmodule_adir = $(includedir)
Index: /branches/rel4/psModules/src/Makefile.in
===================================================================
--- /branches/rel4/psModules/src/Makefile.in	(revision 3057)
+++ /branches/rel4/psModules/src/Makefile.in	(revision 3057)
@@ -0,0 +1,511 @@
+# Makefile.in generated by automake 1.9.2 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 = :
+build_triplet = @build@
+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 =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" \
+	"$(DESTDIR)$(libpsmodule_adir)"
+libLIBRARIES_INSTALL = $(INSTALL_DATA)
+LIBRARIES = $(lib_LIBRARIES)
+ARFLAGS = cru
+libpsmodule_a_AR = $(AR) $(ARFLAGS)
+libpsmodule_a_LIBADD =
+am_libpsmodule_a_OBJECTS = pmFlatField.$(OBJEXT) \
+	pmMaskBadPixels.$(OBJEXT) pmSubtractBias.$(OBJEXT) \
+	psTest.$(OBJEXT) pmSubtractBias.$(OBJEXT) \
+	pmNonLinear.$(OBJEXT) pmReadoutCombine.$(OBJEXT) \
+	pmSubtractSky.$(OBJEXT)
+libpsmodule_a_OBJECTS = $(am_libpsmodule_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link --tag=CC $(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@
+am__tar = @am__tar@
+am__untar = @am__untar@
+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 pmReadoutCombine.c pmSubtractSky.c
+libpsmodule_a_HEADERS = pmFlatField.h pmMaskBadPixels.h pmSubtractBias.h psTest.h pmSubtractBias.h pmNonLinear.h pmReadoutCombine.h pmSubtractSky.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=$(am__strip_dir) \
+	    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=$(am__strip_dir) \
+	    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=$(am__strip_dir) \
+	  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)/pmReadoutCombine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmSubtractBias.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmSubtractSky.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@	DEPDIR=$(DEPDIR) $(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@	DEPDIR=$(DEPDIR) $(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@	DEPDIR=$(DEPDIR) $(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=$(am__strip_dir) \
+	  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=$(am__strip_dir) \
+	  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; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+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:
+	-test -z "$(CONFIG_CLEAN_FILES)" || 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/rel4/psModules/src/config.h.in
===================================================================
--- /branches/rel4/psModules/src/config.h.in	(revision 3057)
+++ /branches/rel4/psModules/src/config.h.in	(revision 3057)
@@ -0,0 +1,76 @@
+/* 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 `mx' library (-lmx). */
+#undef HAVE_LIBMX
+
+/* 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/rel4/psModules/src/mainpage.dox
===================================================================
--- /branches/rel4/psModules/src/mainpage.dox	(revision 3057)
+++ /branches/rel4/psModules/src/mainpage.dox	(revision 3057)
@@ -0,0 +1,130 @@
+/** @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)
+ - Combine readouts (pmReadoutCombine)
+ - Subtract sky (pmSubtractSky)
+
+
+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
+ - Gnome XML C parser and toolkit (libxml2)
+     - Available at http://www.xmlsoft.org
+     - Compatibility tested with version 2-2.6.16-3
+
+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/rel4/psModules/src/parseErrorCodes.pl
===================================================================
--- /branches/rel4/psModules/src/parseErrorCodes.pl	(revision 3057)
+++ /branches/rel4/psModules/src/parseErrorCodes.pl	(revision 3057)
@@ -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/rel4/psModules/src/pmFlatField.c
===================================================================
--- /branches/rel4/psModules/src/pmFlatField.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmFlatField.c	(revision 3057)
@@ -0,0 +1,181 @@
+/** @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.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-06 02:42:03 $
+ *
+ *  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) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmFlatField_NULL_FLAT_READOUT);
+        return false;
+    }
+
+    inImage = in->image;
+    flatImage = flat->image;
+    if (inImage == NULL) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmFlatField_NULL_INPUT_IMAGE);
+        return false;
+    } else if(flatImage == NULL) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_INPUT_IMAGE,
+                 inType);
+        return false;
+    } else if(PS_IS_PSELEMTYPE_COMPLEX(flatType)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_FLAT_IMAGE,
+                 flatType);
+        return false;
+    } else if(maskType != PS_TYPE_MASK) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_MASK_IMAGE,
+                 maskType);
+        return false;
+    } else if(inType != flatType) {
+        psError( 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;                                        \
+                flatImage->data.TYPE[j][i] = 0.0;                                                            \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    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:
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmFlatField_TYPE_UNSUPPORTED,
+                 inType);
+    }
+
+    return true;
+}
Index: /branches/rel4/psModules/src/pmFlatField.h
===================================================================
--- /branches/rel4/psModules/src/pmFlatField.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmFlatField.h	(revision 3057)
@@ -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/rel4/psModules/src/pmFlatFieldErrors.dat
===================================================================
--- /branches/rel4/psModules/src/pmFlatFieldErrors.dat	(revision 3057)
+++ /branches/rel4/psModules/src/pmFlatFieldErrors.dat	(revision 3057)
@@ -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/rel4/psModules/src/pmFlatFieldErrors.h
===================================================================
--- /branches/rel4/psModules/src/pmFlatFieldErrors.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmFlatFieldErrors.h	(revision 3057)
@@ -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/rel4/psModules/src/pmMaskBadPixels.c
===================================================================
--- /branches/rel4/psModules/src/pmMaskBadPixels.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmMaskBadPixels.c	(revision 3057)
@@ -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.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-04 02:02:10 $
+ *
+ *  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) {
+        psError( PS_ERR_BAD_PARAMETER_NULL, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE);
+        return false;
+    }
+
+    inImage = in->image;
+    if (inImage == NULL) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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) {
+        psError( 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)) {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_INPUT_IMAGE,
+                 inType);
+        return false;
+    } else if(maskType!=PS_TYPE_MASK) {
+        psError( 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:
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED,
+                 inType);
+    }
+
+    return false;
+}
Index: /branches/rel4/psModules/src/pmMaskBadPixels.h
===================================================================
--- /branches/rel4/psModules/src/pmMaskBadPixels.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmMaskBadPixels.h	(revision 3057)
@@ -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/rel4/psModules/src/pmMaskBadPixelsErrors.dat
===================================================================
--- /branches/rel4/psModules/src/pmMaskBadPixelsErrors.dat	(revision 3057)
+++ /branches/rel4/psModules/src/pmMaskBadPixelsErrors.dat	(revision 3057)
@@ -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/rel4/psModules/src/pmMaskBadPixelsErrors.h
===================================================================
--- /branches/rel4/psModules/src/pmMaskBadPixelsErrors.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmMaskBadPixelsErrors.h	(revision 3057)
@@ -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/rel4/psModules/src/pmNonLinear.c
===================================================================
--- /branches/rel4/psModules/src/pmNonLinear.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmNonLinear.c	(revision 3057)
@@ -0,0 +1,123 @@
+/** @file  pmNonLinear.c
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-07 20:00:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: The SDR is silent about image types.  Only F32 was implemented.
+ *
+ */
+
+#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 *inputReadout,
+                                    const psPolynomial1D *input1DPoly)
+{
+    PS_PTR_CHECK_NULL(inputReadout, NULL);
+    PS_PTR_CHECK_NULL(inputReadout->image, NULL);
+    PS_IMAGE_CHECK_TYPE(inputReadout->image, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(input1DPoly, NULL);
+
+    psS32 i;
+    psS32 j;
+
+    for (i=0;i<inputReadout->image->numRows;i++) {
+        for (j=0;j<inputReadout->image->numCols;j++) {
+            inputReadout->image->data.F32[i][j] = psPolynomial1DEval(input1DPoly, inputReadout->image->data.F32[i][j]);
+        }
+    }
+    return(inputReadout);
+}
+
+
+/******************************************************************************
+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 *inputReadout,
+                                const psVector *inFlux,
+                                const psVector *outFlux)
+{
+    PS_PTR_CHECK_NULL(inputReadout,NULL);
+    PS_PTR_CHECK_NULL(inputReadout->image,NULL);
+    PS_IMAGE_CHECK_TYPE(inputReadout->image, PS_TYPE_F32, NULL);
+    PS_PTR_CHECK_NULL(inFlux,NULL);
+    if (inFlux->n < 2) {
+        psError(PS_ERR_UNKNOWN,true, "pmNonLinearityLookup(): input vector less than 2 elements.  Returning inputReadout image.");
+        return(inputReadout);
+    }
+    PS_PTR_CHECK_NULL(outFlux,NULL);
+    psS32 tableSize = inFlux->n;
+    if (inFlux->n != outFlux->n) {
+        tableSize = PS_MIN(inFlux->n, outFlux->n);
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (%d, %d)\n", inFlux->n, outFlux->n);
+    }
+    PS_VECTOR_CHECK_TYPE(inFlux, PS_TYPE_F32, NULL);
+    PS_VECTOR_CHECK_TYPE(outFlux, PS_TYPE_F32, NULL);
+
+    psS32 i;
+    psS32 j;
+    psS32 binNum;
+    psScalar x;
+    psS32 numPixels = 0;
+    psF32 slope;
+
+    x.type.type = PS_TYPE_F32;
+    for (i=0;i<inputReadout->image->numRows;i++) {
+        for (j=0;j<inputReadout->image->numCols;j++) {
+            x.data.F32 = inputReadout->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.
+                inputReadout->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.
+                inputReadout->image->data.F32[i][j] = outFlux->data.F32[tableSize-1];
+                numPixels++;
+
+            } else if (binNum < -2) {
+                // We get here if there was some other problem.
+                psError(PS_ERR_UNKNOWN,true, "pmNonLinearityLookup(): Could not perform p_psVectorBinDisect().  Returning inputReadout image.");
+                return(inputReadout);
+                numPixels++;
+            } else {
+                // Perform linear interpolation.
+                slope = (outFlux->data.F32[binNum+1] - outFlux->data.F32[binNum]) /
+                        (inFlux->data.F32[binNum+1]  - inFlux->data.F32[binNum]);
+                inputReadout->image->data.F32[i][j] = outFlux->data.F32[binNum] +
+                                                      ((x.data.F32 - inFlux->data.F32[binNum]) * slope);
+            }
+        }
+    }
+    if (numPixels > 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmNonLinear.c: pmNonLinearityLookup(): %d pixels outside table.", numPixels);
+    }
+    return(inputReadout);
+}
Index: /branches/rel4/psModules/src/pmNonLinear.h
===================================================================
--- /branches/rel4/psModules/src/pmNonLinear.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmNonLinear.h	(revision 3057)
@@ -0,0 +1,26 @@
+/** @file  pmNonLinear.h
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 19:58:18 $
+ *
+ *  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/rel4/psModules/src/pmReadoutCombine.c
===================================================================
--- /branches/rel4/psModules/src/pmReadoutCombine.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmReadoutCombine.c	(revision 3057)
@@ -0,0 +1,374 @@
+/** @file  pmReadoutCombine.c
+ *
+ *  This file will contain a module which will combine multiple readout images.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-07 20:00:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "pmReadoutCombine.h"
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions DetermineNumBits(psStatsOptions data)
+{
+    psS32 i;
+    psU64 tmpData = data;
+    psS32 numBits = 0;
+
+    for (i=0;i<8 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
+            numBits++;
+        }
+        tmpData = tmpData >> 1;
+    }
+    return(numBits);
+}
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ 
+XXX: Must add support for S16 and S32 types.  F32 currently supported.
+ *****************************************************************************/
+psImage *pmReadoutCombine(psImage *output,
+                          const psList *inputs,
+                          psCombineParams *params,
+                          const psVector *zero,
+                          const psVector *scale,
+                          bool applyZeroScale,
+                          psF32 gain,
+                          psF32 readnoise)
+{
+    PS_PTR_CHECK_NULL(inputs, NULL);
+    PS_PTR_CHECK_NULL(params, NULL);
+    PS_PTR_CHECK_NULL(params->stats, NULL);
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+        //        PS_VECTOR_CHECK_TYPE_S16_S32_F32(zero, NULL);
+    }
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+        //        PS_VECTOR_CHECK_TYPE_S16_S32_F32(scale, NULL);
+    }
+    if ((zero != NULL) && (scale != NULL)) {
+        PS_VECTOR_CHECK_TYPE_EQUAL(zero, scale, NULL);
+        // PS_VECTOR_CHECK_TYPE_S16_S32_F32(scale, NULL);
+    }
+
+    psStats *stats = params->stats;
+    psS32 i;
+    psS32 j;
+    psS32 maxInputCols = 0;
+    psS32 maxInputRows = 0;
+    psS32 minInputCols = PS_MAX_S32;
+    psS32 minInputRows = PS_MAX_S32;
+    psListElem *tmpInput = NULL;
+    psReadout *tmpReadout = NULL;
+    psS32 numInputs = 0;
+    psS32 tmpI;
+    psElemType outputType = PS_TYPE_F32;
+
+    if (1 < DetermineNumBits(params->stats->options)) {
+        psError(PS_ERR_UNKNOWN, true,
+                "Multiple statistical options have been requested.  Returning NULL.\n");
+        return(NULL);
+    }
+
+    //
+    // We step through each readout in the input image list.  If any readout is
+    // NULL, empty, or has the wrong type, we generate an error and return
+    // NULL.  We determine how big of an output image is needed to combine
+    // these input images.  We do this by taking the
+    //     max(readout->col0 + readout->numCols + image->col0 + image->numCols)
+    //     max(readout->row0 + readout->numRows + image->row0 + image->numRows)
+    // We then compare that to
+    //     output->col0 + output->numCols
+    //     output->row0 + output->numRows
+    // to determine if the output image actually stores that pixel.  A similar
+    // thing is done for the minimum row and column.
+    //
+    tmpInput = (psListElem *) inputs->head;
+    while (NULL != tmpInput) {
+        tmpReadout = (psReadout *) tmpInput->data;
+        PS_READOUT_CHECK_NULL(tmpReadout, output);
+        PS_READOUT_CHECK_EMPTY(tmpReadout, output);
+        PS_READOUT_CHECK_TYPE(tmpReadout, PS_TYPE_F32, output);
+        outputType = tmpReadout->image->type.type;
+
+        minInputRows = PS_MIN(minInputRows,
+                              (tmpReadout->row0 + tmpReadout->image->row0));
+        tmpI = tmpReadout->row0 +
+               tmpReadout->image->row0 +
+               tmpReadout->image->numRows;
+        maxInputRows = PS_MAX(maxInputRows, tmpI);
+
+        minInputCols = PS_MIN(minInputCols,
+                              (tmpReadout->col0 + tmpReadout->image->col0));
+        tmpI = tmpReadout->col0 +
+               tmpReadout->image->col0 +
+               tmpReadout->image->numCols;
+        maxInputCols = PS_MAX(maxInputCols, tmpI);
+        tmpInput = tmpInput->next;
+        numInputs++;
+    }
+
+    // We ensure that the zero vector is of the proper size.
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+        if (numInputs > zero->n) {
+            psError(PS_ERR_UNKNOWN, true, "zero vector has incorrect size (%d).  Returning NULL.\n", zero->n);
+            return(NULL);
+        } else if (numInputs < zero->n) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the zero vector too many elements (%d)\n", zero->n);
+        }
+    }
+
+    // We ensure that the scale vector is of the proper size.
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+        if (numInputs > scale->n) {
+            psError(PS_ERR_UNKNOWN, true, "scale vector has incorrect size (%d).  Returning NULL.\n", scale->n);
+            return(NULL);
+        } else if (numInputs < scale->n) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the scale vector has too many elements (%d)\n", scale->n);
+        }
+    }
+
+    // At this point, the following variables have been computed:
+    // maxInputRows: the largest input row value, in output image space.
+    // maxInputCols: the largest input column value, in output image space.
+    // minInputRows: the smallest input row value, in output image space.
+    // minInputCols: the smallest input column value, in output image space.
+    //
+    if (output == NULL) {
+        output = psImageAlloc(maxInputCols-minInputCols,
+                              maxInputRows-minInputRows, outputType);
+        *(psS32 *) &(output->col0) = minInputCols;
+        *(psS32 *) &(output->row0) = minInputRows;
+    } else {
+        PS_IMAGE_CHECK_TYPE(output, PS_TYPE_F32, NULL);
+        if (((output->col0 + output->numCols) < maxInputCols) ||
+                ((output->row0 + output->numRows) < maxInputRows)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Output image (%d, %d) is too small to hold combined images.  Returning NULL.\n",
+                    output->row0 + output->numRows,
+                    output->col0 + output->numCols);
+            return(NULL);
+        }
+
+        if ((output->col0 > minInputCols) || (output->row0 > minInputRows)) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Output image offset is larger then input image offset.  Returning NULL.\n");
+            return(NULL);
+        }
+    }
+
+    psVector *tmpPixels = psVectorAlloc(numInputs, PS_TYPE_F32);
+    psVector *tmpPixelErrors = psVectorAlloc(numInputs, PS_TYPE_F32);
+    psVector *tmpPixelMask = psVectorAlloc(numInputs, PS_TYPE_U8);
+    psVector *tmpPixelMaskNKeep = psVectorAlloc(numInputs, PS_TYPE_U8);
+    psVector *outRowLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outRowUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psReadout **tmpReadouts = (psReadout **) psAlloc(numInputs * sizeof(psReadout *));
+
+    // For each input readout, we create a pointer to that readout in
+    // "tmpReadouts[]", and we store the min/max pixel indices for that
+    // readout, in output image coordinates, in the psVectors
+    // (outRowLower, outColLower, outRowUpper, outColUpper).
+    i = 0;
+    tmpInput = (psListElem *) inputs->head;
+    while (NULL != tmpInput) {
+        tmpReadouts[i] = (psReadout *) tmpInput->data;
+        outRowLower->data.U32[i] = tmpReadouts[i]->row0 + tmpReadouts[i]->image->row0;
+        outColLower->data.U32[i] = tmpReadouts[i]->col0 + tmpReadouts[i]->image->col0;
+        outRowUpper->data.U32[i] = tmpReadouts[i]->row0 +
+                                   tmpReadouts[i]->image->row0 +
+                                   tmpReadouts[i]->image->numRows;
+        outColUpper->data.U32[i] = tmpReadouts[i]->col0 +
+                                   tmpReadouts[i]->image->col0 +
+                                   tmpReadouts[i]->image->numCols;
+        tmpInput = tmpInput->next;
+        i++;
+    }
+
+    // We loop through each pixel in the output image.  We loop through each
+    // input readout.  We determine if that output pixel is contained in the
+    // image from that readout.  If so, we save it in psVector tmpPixels.
+    // If not, we set a mask for that element in tmpPixels.  Then, we mask off
+    // pixels not between fracLow and fracHigh.  Then we call the vector
+    // stats routine on those pixels/mask.  Then we set the output pixel value
+    // to the result of the stats call.
+
+    for (i = output->row0; i < (output->row0 + output->numRows) ; i++) {
+        for (j = output->col0; j < (output->col0 + output->numCols) ; j++) {
+            for (psS32 r = 0; r < numInputs ; r++) {
+                //  printf("[%d][%d]: [%d][%d] to [%d][%d]\n", i, j, outRowLower->data.U32[r], outColLower->data.U32[r], outRowUpper->data.U32[r], outColUpper->data.U32[r]);
+                if ((outRowLower->data.U32[r] <= i) &&
+                        (outColLower->data.U32[r] <= j) &&
+                        (outRowUpper->data.U32[r] > i) &&
+                        (outColUpper->data.U32[r] > j)) {
+
+                    psS32 imageRow = i - (tmpReadouts[r]->row0 +
+                                          tmpReadouts[r]->image->row0);
+                    psS32 imageCol = j - (tmpReadouts[r]->col0 +
+                                          tmpReadouts[r]->image->col0);
+
+                    if ((NULL == tmpReadouts[r]->mask) ||
+                            !(params->maskVal && tmpReadouts[r]->mask->data.U8[imageRow][imageCol])) {
+                        tmpPixels->data.F32[r] = tmpReadouts[r]->image->data.F32[imageRow][imageCol];
+                        tmpPixelMask->data.U8[r] = 0;
+                    } else {
+                        tmpPixels->data.F32[r] = 0.0;
+                        tmpPixelMask->data.U8[r] = 1;
+                    }
+                } else {
+                    tmpPixels->data.F32[r] = 0.0;
+                    tmpPixelMask->data.U8[r] = 1;
+                }
+                // printf("readout[%d], image [%d][%d] is %f\n", r, i, j, tmpPixels->data.F32[r]);
+            }
+            // At this point, we have scanned all input readouts for this
+            // one output pixel.
+
+            // Determine how many pixels lie between fracLow and fracHigh.
+            psS32 pixelCount = 0;
+            for (psS32 r = 0; r < numInputs ; r++) {
+                if (tmpPixelMask->data.U8[r] == 0) {
+                    if ((params->fracLow <= tmpPixels->data.F32[r]) &&
+                            (params->fracHigh >= tmpPixels->data.F32[r])) {
+                        pixelCount++;
+                    }
+                }
+            }
+
+            // If more than params->nKeep pixels lie between the valid range,
+            // then loop through the pixels, and mask away any pixels outside
+            // that range.
+            if (pixelCount >= params->nKeep) {
+                for (psS32 r = 0; r < numInputs ; r++) {
+                    if (tmpPixelMask->data.U8[r] == 0) {
+                        if ((params->fracLow <= tmpPixels->data.F32[r]) &&
+                                (params->fracHigh >= tmpPixels->data.F32[r])) {
+                            tmpPixelMaskNKeep->data.U8[r] = 0;
+                        } else {
+                            tmpPixelMaskNKeep->data.U8[r] = 1;
+                        }
+                    }
+                }
+            }
+
+            if ((gain > 0.0) && (readnoise >= 0.0)) {
+                psF32 x;
+                psF32 sigma;
+                if (applyZeroScale == true) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        if (zero != NULL) {
+                            x = zero->data.F32[r];
+                        } else {
+                            x = 0.0;
+                        }
+                        if (scale != NULL) {
+                            x+= tmpPixels->data.F32[r] * scale->data.F32[r];
+                        } else {
+                            x+= tmpPixels->data.F32[r];
+                        }
+                        sigma = PS_SQRT_F32((readnoise*readnoise) + gain * x) / gain;
+
+                        tmpPixelErrors->data.F32[r] = sigma;
+                        tmpPixels->data.F32[r]= x;
+                    }
+                } else {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        x= tmpPixels->data.F32[r];
+
+                        if (zero != NULL) {
+                            sigma = zero->data.F32[r];
+                        } else {
+                            sigma = 0.0;
+                        }
+                        if (scale != NULL) {
+                            sigma+= tmpPixels->data.F32[r] * scale->data.F32[r];
+                        } else {
+                            sigma+= tmpPixels->data.F32[r];
+                        }
+                        sigma = PS_SQRT_F32((readnoise*readnoise) + (gain * sigma)) / gain;
+
+                        tmpPixelErrors->data.F32[r] = sigma;
+                        tmpPixels->data.F32[r]= x;
+                    }
+                }
+                // Calculate the specified statistic on the stack of pixels.
+                psStats *rc = psVectorStats(stats,
+                                            tmpPixels,
+                                            tmpPixelErrors,
+                                            tmpPixelMaskNKeep,
+                                            1);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning NULL.\n");
+                    return(NULL);
+                }
+            } else {
+                if (scale != NULL) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        tmpPixels->data.F32[r]*= scale->data.F32[r];
+                    }
+                }
+
+                // We add the zero vector, if non-NULL.
+                if (zero != NULL) {
+                    for (psS32 r = 0; r < numInputs ; r++) {
+                        tmpPixels->data.F32[r]+= zero->data.F32[r];
+                    }
+                }
+
+                // Calculate the specified statistic on the stack of pixels.
+                psStats *rc = psVectorStats(stats,
+                                            tmpPixels,
+                                            NULL,
+                                            tmpPixelMaskNKeep,
+                                            1);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning NULL.\n");
+                    return(NULL);
+                }
+            }
+
+
+            // Set the pixel value in the output image to the stat value.
+            double statValue;
+            if (!p_psGetStatValue(stats, &statValue)) {
+                psError(PS_ERR_UNKNOWN, true, "Could not determine stats value.  Returning NULL.\n");
+                return(NULL);
+            } else {
+                output->data.F32[i-output->row0][j-output->col0] = (psF32) statValue;
+            }
+        }
+    }
+
+    psFree(tmpPixels);
+    psFree(tmpPixelErrors);
+    psFree(tmpPixelMask);
+    psFree(tmpPixelMaskNKeep);
+    psFree(outRowLower);
+    psFree(outRowUpper);
+    psFree(outColLower);
+    psFree(outColUpper);
+    psFree(tmpReadouts);
+
+    return(output);
+}
Index: /branches/rel4/psModules/src/pmReadoutCombine.h
===================================================================
--- /branches/rel4/psModules/src/pmReadoutCombine.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmReadoutCombine.h	(revision 3057)
@@ -0,0 +1,47 @@
+/** @file  pmReadoutCombine.h
+ *
+ *  This file will contain a module which will combine multiple readout images.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 23:42:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_READOUT_COMBINE_H)
+#define PM_READOUT_COMBINE_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "psConstants.h"
+// XXX: have Desonia do this correctly.
+#include "../../psLib/src/dataManip/psConstants.h"
+
+typedef struct
+{
+    psStats *stats;
+    unsigned int maskVal;
+    float fracHigh;
+    float fracLow;
+    int nKeep;
+}
+psCombineParams;
+
+psImage *pmReadoutCombine(psImage *output,
+                          const psList *inputs,
+                          psCombineParams *params,
+                          const psVector *zero,
+                          const psVector *scale,
+                          bool applyZeroScale,
+                          float gain,
+                          float readnoise);
+
+#endif
Index: /branches/rel4/psModules/src/pmSubtractBias.c
===================================================================
--- /branches/rel4/psModules/src/pmSubtractBias.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmSubtractBias.c	(revision 3057)
@@ -0,0 +1,641 @@
+/** @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.30 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 19:58:18 $
+ *
+ *  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)
+{
+    psS32 i;
+    psS32 j;
+
+    if (bias == NULL) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.c: psSubtractFrame(): bias frame is NULL.  Returning original image.\n");
+        return(in);
+    }
+
+    if (((in->image)->numRows + in->row0 - bias->row0) > (bias->image)->numRows) {
+        psError(PS_ERR_UNKNOWN,true, "bias image does not have enough rows.  Returning in image\n");
+        return(in);
+    }
+    if (((in->image)->numCols + in->row0 - bias->row0) > (bias->image)->numCols) {
+        psError(PS_ERR_UNKNOWN,true, "bias image does not have enough columns.  Returning in image\n");
+        return(in);
+    }
+
+    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.
+ *****************************************************************************/
+psImage *p_psImageSubtractScalar(psImage *image,
+                                 psF32 scalar)
+{
+    for (psS32 i=0;i<image->numRows;i++) {
+        for (psS32 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).  The higher priority options are
+listed lower in the code.
+ *****************************************************************************/
+psStatsOptions GenNewStatOptions(const psStats *stat)
+{
+    psS32 numOptions = 0;
+    psStatsOptions opt = 0;
+
+    if (stat->options & PS_STAT_ROBUST_MODE) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MODE;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_CLIPPED_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_CLIPPED_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_SAMPLE_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_SAMPLE_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_SAMPLE_MEAN) {
+        numOptions++;
+        opt = PS_STAT_SAMPLE_MEAN;
+    }
+
+
+    if (numOptions == 0) {
+        psError(PS_ERR_UNKNOWN,true, "No statistics options have been specified.\n");
+    }
+    if (numOptions != 1) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.c: GenNewStatOptions(): 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,
+                              psS32 n,
+                              void *fitSpec,
+                              pmFit fit)
+{
+    psTrace(".psModule.pmSubtracBias.ScaleOverscanVector", 4,
+            "---- ScaleOverscanVector() begin (%d -> %d) ----\n", overscanVector->n, n);
+
+    if (NULL == overscanVector) {
+        return(overscanVector);
+    }
+
+    // Allocate the new vector.
+    psVector *newVec = psVectorAlloc(n, PS_TYPE_F32);
+
+    //
+    // If the new vector is the same size as the old, simply copy the data.
+    if (n == overscanVector->n) {
+        for (psS32 i = 0 ; i < n ; i++) {
+            newVec->data.F32[i] = overscanVector->data.F32[i];
+        }
+        return(newVec);
+    }
+    psPolynomial1D *myPoly;
+    psSpline1D *mySpline;
+    psF32 x;
+    psS32 i;
+
+    if (fit == PM_FIT_POLYNOMIAL) {
+        // Fit a polynomial to the old overscan vector.
+        myPoly = (psPolynomial1D *) fitSpec;
+        PS_POLY_CHECK_NULL(myPoly, NULL);
+        myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+        if (myPoly == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): Could not fit a polynomial to the psVector.\n");
+            return(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 = ((psF32) i) * ((psF32) overscanVector->n) / ((psF32) n);
+            newVec->data.F32[i] = psPolynomial1DEval(myPoly, x);
+        }
+    } else if (fit == PM_FIT_SPLINE) {
+        psS32 mustFreeSpline = 0;
+        // Fit a spline to the old overscan vector.
+        mySpline = (psSpline1D *) fitSpec;
+        if (mySpline == NULL) {
+            mustFreeSpline = 1;
+        }
+
+        //
+        // NOTE: Since the X arg in the psVectorFitSpline1D() function is NULL,
+        // splines enpoints will be from 0.0 to overscanVector->n-1.  Must scale
+        // properly when doing the spline eval.
+        //
+        mySpline = psVectorFitSpline1D(mySpline, NULL, overscanVector, NULL);
+        if (mySpline == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): Could not fit a spline to the psVector.\n");
+            return(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++) {
+            // Scale to [0 : overscanVector->n - 1]
+            x = ((psF32) i) * ((psF32) (overscanVector->n-1)) / ((psF32) n);
+            newVec->data.F32[i] = psSpline1DEval(mySpline, x);
+        }
+        if (mustFreeSpline ==1) {
+            psFree(mySpline);
+        }
+
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "unknown fit type.  Returning NULL.\n");
+        psFree(newVec);
+        return(NULL);
+    }
+
+    psTrace(".psModule.pmSubtracBias.ScaleOverscanVector", 4,
+            "---- ScaleOverscanVector() exit ----\n");
+    return(newVec);
+}
+
+/******************************************************************************
+XXX: The SDRS does not specify type support.  F32 is implemented here.
+ *****************************************************************************/
+psReadout *pmSubtractBias(psReadout *in,
+                          void *fitSpec,
+                          const psList *overscans,
+                          pmOverscanAxis overScanAxis,
+                          psStats *stat,
+                          psS32 nBinOrig,
+                          pmFit fit,
+                          const psReadout *bias)
+{
+    psTrace(".psModule.pmSubtracBias.pmSubtractBias", 4,
+            "---- pmSubtractBias() begin ----\n");
+    PS_READOUT_CHECK_NULL(in, NULL);
+    PS_READOUT_CHECK_EMPTY(in, NULL);
+    PS_READOUT_CHECK_TYPE(in, PS_TYPE_F32, NULL);
+
+    //
+    // If the overscans != NULL, then check the type of each image.
+    //
+    if (overscans != NULL) {
+        psListElem *tmpOverscan = (psListElem *) overscans->head;
+        while (NULL != tmpOverscan) {
+            psImage *myOverscanImage = (psImage *) tmpOverscan->data;
+            PS_IMAGE_CHECK_TYPE(myOverscanImage, PS_TYPE_F32, NULL);
+            tmpOverscan = tmpOverscan->next;
+        }
+    }
+
+    if ((overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE)) {
+        psError(PS_ERR_UNKNOWN,true, "(overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image\n");
+        return(in);
+    }
+
+    // Check for an unallowable pmFit.
+    if ((fit != PM_OVERSCAN_NONE) &&
+            (fit != PM_OVERSCAN_ROWS) &&
+            (fit != PM_OVERSCAN_COLUMNS) &&
+            (fit != PM_OVERSCAN_ALL)) {
+        psError(PS_ERR_UNKNOWN, true, "fit is unallowable (%d).  Returning in image.\n", fit);
+        return(in);
+    }
+    // Check for an unallowable pmOverscanAxis.
+    if ((overScanAxis != PM_OVERSCAN_NONE) &&
+            (overScanAxis != PM_OVERSCAN_ROWS) &&
+            (overScanAxis != PM_OVERSCAN_COLUMNS) &&
+            (overScanAxis != PM_OVERSCAN_ALL)) {
+        psError(PS_ERR_UNKNOWN, true, "overScanAxis is unallowable (%d).  Returning in image.\n", overScanAxis);
+        return(in);
+    }
+    psS32 i;
+    psS32 j;
+    psS32 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 = NULL;
+    psSpline1D *mySpline = NULL;
+    psS32 nBin;
+
+    //
+    //  Create a static stats data structure and determine the highest
+    //  priority stats option.
+    //
+    static psStats *myStats = NULL;
+    if (myStats == NULL) {
+        myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        p_psMemSetPersistent(myStats, true);
+    }
+    if (stat != NULL) {
+        myStats->options = GenNewStatOptions(stat);
+    }
+
+
+
+
+    if (overScanAxis == PM_OVERSCAN_NONE) {
+        if (fit != PM_FIT_NONE) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.\n");
+        }
+
+        if (overscans != NULL) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractBias.(): overScanAxis equals NONE and overscans does not equal NULL.  Proceeding to full fram subtraction.\n");
+        }
+        return(psSubtractFrame(in, bias));
+    }
+
+    if ((overScanAxis == PM_OVERSCAN_ALL) && (fit != PM_FIT_NONE)) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.\n");
+    }
+
+
+    //
+    // We subtract each overscan region from the image data.
+    // If we get here we know that overscans != NULL.
+    //
+
+    if (overScanAxis == PM_OVERSCAN_ALL) {
+        tmpOverscan = (psListElem *) overscans->head;
+        while (NULL != tmpOverscan) {
+            myOverscanImage = (psImage *) tmpOverscan->data;
+
+            PS_IMAGE_CHECK_TYPE(myOverscanImage, PS_TYPE_F32, NULL);
+            psStats *rc = psImageStats(myStats, myOverscanImage, NULL, 0xffffffff);
+            if (rc == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+                return(in);
+            }
+            if (false == p_psGetStatValue(myStats, &statValue)) {
+                psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                return(in);
+            }
+            p_psImageSubtractScalar(in->image, statValue);
+
+            tmpOverscan = tmpOverscan->next;
+        }
+        return(in);
+    }
+
+    // This check is redundant with above code.
+    if (!((overScanAxis == PM_OVERSCAN_ROWS) || (overScanAxis == PM_OVERSCAN_COLUMNS))) {
+        psError(PS_ERR_UNKNOWN, true, "overScanAxis is unallowable (%d).\nReturning in image.\n", overScanAxis);
+        return(in);
+    }
+
+    tmpOverscan = (psListElem *) overscans->head;
+    while (NULL != tmpOverscan) {
+        myOverscanImage = (psImage *) tmpOverscan->data;
+
+        if (overScanAxis == PM_OVERSCAN_ROWS) {
+            if (myOverscanImage->numCols != (in->image)->numCols) {
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractBias.(): overscan image has %d columns, input image has %d columns\n",
+                         myOverscanImage->numCols, in->image->numCols);
+            }
+
+            // We create a row vector and subtract this vector from image.
+            // XXX: Is there a better way to extract a psVector from a psImage without
+            // having to copy every element in that vector?
+            overscanVector = psVectorAlloc(myOverscanImage->numCols, PS_TYPE_F32);
+            for (i=0;i<overscanVector->n;i++) {
+                overscanVector->data.F32[i] = 0.0;
+            }
+            tmpRow = psVectorAlloc(myOverscanImage->numRows, PS_TYPE_F32);
+
+            // For each column of the input image, loop through every row,
+            // collect the pixel in that row, then performed the specified
+            // statistical op on those pixels.  Store this in overscanVector.
+            for (i=0;i<myOverscanImage->numCols;i++) {
+                for (j=0;j<myOverscanImage->numRows;j++) {
+                    tmpRow->data.F32[j] = myOverscanImage->data.F32[j][i];
+                }
+                psStats *rc = psVectorStats(myStats, tmpRow, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                overscanVector->data.F32[i] = statValue;
+            }
+            psFree(tmpRow);
+
+            // Scale the overscan vector to the size of the input image.
+            if (overscanVector->n != in->image->numCols) {
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector,
+                                                           in->image->numCols,
+                                                           fitSpec, fit);
+                    if (newVec == NULL) {
+                        psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): could not scale the overscan vector.  Returning in image.\n");
+                        return(in);
+                    }
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                } else {
+                    psError(PS_ERR_UNKNOWN, true, "Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+        }
+
+        if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+            if (myOverscanImage->numRows != (in->image)->numRows) {
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractBias.(): overscan image has %d rows, input image has %d rows\n",
+                         myOverscanImage->numRows, in->image->numRows);
+            }
+
+            // 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(myOverscanImage->numCols, PS_TYPE_F32);
+
+            // For each row of the input image, loop through every column,
+            // collect the pixel in that row, then performed the specified
+            // statistical op on those pixels.  Store this in overscanVector.
+            for (i=0;i<myOverscanImage->numRows;i++) {
+                for (j=0;j<myOverscanImage->numCols;j++) {
+                    tmpCol->data.F32[j] = myOverscanImage->data.F32[i][j];
+                }
+                psStats *rc = psVectorStats(myStats, tmpCol, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                overscanVector->data.F32[i] = statValue;
+            }
+            psFree(tmpCol);
+
+            // Scale the overscan vector to the size of the input image.
+            if (overscanVector->n != in->image->numRows) {
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector,
+                                                           in->image->numRows,
+                                                           fitSpec, fit);
+                    if (newVec == NULL) {
+                        psError(PS_ERR_UNKNOWN, false, "ScaleOverscanVector(): could not scale the overscan vector.  Returning in image.\n");
+                        return(in);
+                    }
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                } else {
+                    psError(PS_ERR_UNKNOWN, true, "Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+        }
+
+        //
+        // Re-bin the overscan vector (change its length).
+        //
+        // Only if nBinOrig > 1.
+        if ((nBinOrig > 1) && (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;
+                    }
+                }
+                psStats *rc = psVectorStats(myStats, binVec, NULL, NULL, 0);
+                if (rc == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                if (false ==  p_psGetStatValue(rc, &statValue)) {
+                    psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine result from requested statistical operation.  Returning in image.\n");
+                    return(in);
+                }
+                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;
+        }
+
+        // At this point the number of data points in overscanVector should be
+        // equal to the number of rows/columns (whatever is appropriate) in the
+        // image divided by numBins.
+        //
+
+
+        //
+        // This doesn't seem right.  The only way to do a spline fit is if,
+        // by SDRS requirements, fitSpec is not-NULL>  But in order for it
+        // to be non-NULL, someone must have called psSpline1DAlloc() with
+        // the min, max, and number of splines.
+        //
+        if (!((fitSpec == NULL) || (fit == PM_FIT_NONE))) {
+            //
+            // Fit a polynomial or spline to the overscan vector.
+            //
+            if (fit == PM_FIT_POLYNOMIAL) {
+                myPoly = (psPolynomial1D *) fitSpec;
+                myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+                if (myPoly == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "Could not fit a polynomial to overscan vector.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            } else if (fit == PM_FIT_SPLINE) {
+                mySpline = (psSpline1D *) fitSpec;
+                mySpline = psVectorFitSpline1D(mySpline, NULL, overscanVector, NULL);
+                if (mySpline == NULL) {
+                    psError(PS_ERR_UNKNOWN, false, "Could not fit a spline to overscan vector.  Returning in image.\n");
+                    psFree(overscanVector);
+                    return(in);
+                }
+            }
+
+            //
+            // Subtract fitted overscan vector row-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_ROWS) {
+                for (i=0;i<(in->image)->numCols;i++) {
+                    psF32 tmpF32 = 0.0;
+                    if (fit == PM_FIT_POLYNOMIAL) {
+                        tmpF32 = psPolynomial1DEval(myPoly, ((psF32) i) / ((psF32) nBin));
+                    } else if (fit == PM_FIT_SPLINE) {
+                        tmpF32 = psSpline1DEval(mySpline, ((psF32) i) / ((psF32) nBin));
+                    }
+                    for (j=0;j<(in->image)->numRows;j++) {
+                        (in->image)->data.F32[j][i]-= tmpF32;
+                    }
+                }
+            }
+
+            //
+            // Subtract fitted overscan vector column-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+                for (i=0;i<(in->image)->numRows;i++) {
+                    psF32 tmpF32 = 0.0;
+                    if (fit == PM_FIT_POLYNOMIAL) {
+                        tmpF32 = psPolynomial1DEval(myPoly, ((psF32) i) / ((psF32) nBin));
+                    } else if (fit == PM_FIT_SPLINE) {
+                        tmpF32 = psSpline1DEval(mySpline, ((psF32) i) / ((psF32) nBin));
+                    }
+
+                    for (j=0;j<(in->image)->numCols;j++) {
+                        (in->image)->data.F32[i][j]-= tmpF32;
+                    }
+                }
+            }
+        } else {
+            //
+            // If we get here, then no polynomials were fit to the overscan
+            // vector.  We simply subtract it, taking into account binning,
+            // from the image.
+            //
+
+            //
+            // 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;
+    }
+
+    psTrace(".psModule.pmSubtracBias.pmSubtractBias", 4,
+            "---- pmSubtractBias() exit ----\n");
+
+    if (bias != NULL) {
+        return(psSubtractFrame(in, bias));
+    }
+    return(in);
+}
+
+
Index: /branches/rel4/psModules/src/pmSubtractBias.h
===================================================================
--- /branches/rel4/psModules/src/pmSubtractBias.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmSubtractBias.h	(revision 3057)
@@ -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/rel4/psModules/src/pmSubtractSky.c
===================================================================
--- /branches/rel4/psModules/src/pmSubtractSky.c	(revision 3057)
+++ /branches/rel4/psModules/src/pmSubtractSky.c	(revision 3057)
@@ -0,0 +1,676 @@
+/** @file  pmSubtractSky.c
+ *
+ *  This file will contain a module which will create a model of the
+ *  background sky and subtract that from the input image.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-19 00:06:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+xd *
+ */
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+#include "psConstants.h"
+#include "pmSubtractSky.h"
+
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions p_psDetermineNumBits(psStatsOptions data)
+{
+    psS32 i;
+    psU64 tmpData = data;
+    psS32 numBits = 0;
+
+    for (i=0;i<8 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
+            numBits++;
+        }
+        tmpData = tmpData >> 1;
+    }
+    return(numBits);
+}
+
+/******************************************************************************
+getHighestPriorityStatOption(statOptions): this routine takes as input a
+psStats->options with multiple options set and returns one with a single
+option set according to the precedence set in the SDRS.
+ *****************************************************************************/
+psU64 getHighestPriorityStatOption(psU64 statOptions)
+{
+    if (statOptions & PS_STAT_SAMPLE_MEAN) {
+        return(PS_STAT_SAMPLE_MEAN);
+    } else if (statOptions & PS_STAT_SAMPLE_MEDIAN) {
+        return(PS_STAT_SAMPLE_MEDIAN);
+    } else if (statOptions & PS_STAT_CLIPPED_MEAN) {
+        return(PS_STAT_CLIPPED_MEAN);
+    } else if (statOptions & PS_STAT_ROBUST_MEAN) {
+        return(PS_STAT_ROBUST_MEAN);
+    } else if (statOptions & PS_STAT_ROBUST_MEDIAN) {
+        return(PS_STAT_ROBUST_MEDIAN);
+    } else if (statOptions & PS_STAT_ROBUST_MODE) {
+        return(PS_STAT_ROBUST_MODE);
+    }
+    psError(PS_ERR_UNKNOWN, true, "Unallowable option requested for statistically binning image pixels.\n");
+    return(-1);
+}
+
+/******************************************************************************
+psImage *binImage(origImage, binFactor, statOptions): This routine takes an
+input psImage and scales it smaller by a factor of binFactor.  The statistic
+used in combining input pixels is specified in statOptions.
+ 
+XXX: use static vectors for myStats, binVector and binMask.
+XXX: I coded this before I was aware of a psLib reBin function.  I don't
+use this function in this module.  I'm keeping it here in the event that
+requirements change and we might need a custom reBin function.
+ *****************************************************************************/
+psImage *binImage(psImage *origImage,
+                  int binFactor,
+                  psStatsOptions statOptions)
+{
+    if (binFactor <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: binImage(): binFactor is %d\n", binFactor);
+        return(origImage);
+    }
+    if (binFactor == 1) {
+        return(origImage);
+    }
+
+    psVector *binVector = psVectorAlloc(binFactor * binFactor, PS_TYPE_F32);
+    psVector *binMask = psVectorAlloc(binFactor * binFactor, PS_TYPE_U8);
+    psStats *myStats = psStatsAlloc(statOptions);
+
+    for (psS32 row = 0; row < origImage->numRows ; row+=binFactor) {
+        for (psS32 col = 0; col < origImage->numCols ; col+=binFactor) {
+            psS32 count = 0;
+            for (psS32 binRow = 0; binRow <= binFactor ; binRow++) {
+                for (psS32 binCol = 0; binCol <= binFactor ; binCol++) {
+                    if (((row + binRow) < origImage->numRows) &&
+                            ((col + binCol) < origImage->numCols)) {
+                        binVector->data.F32[count] =
+                            origImage->data.F32[row + binRow][col + binCol];
+                        binMask->data.U8[count] = 0;
+                    } else {
+                        binVector->data.F32[count] = 0.0;
+                        binMask->data.U8[count] = 1;
+                    }
+                    count++;
+                }
+            }
+            psStats *rc1 = psVectorStats(myStats, binVector, NULL, binMask, 1);
+            if (rc1 == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psVectorStats(): could not perform requested statistical operation.  Returning in image.\n");
+                return(origImage);
+            }
+            psF64 statValue;
+            psBool rc = p_psGetStatValue(rc1, &statValue);
+
+            if (rc == true) {
+                origImage->data.F32[row][col] = (psF32) statValue;
+            } else {
+                origImage->data.F32[row][col] = 0.0;
+                psLogMsg(__func__, PS_LOG_WARN,
+                         "WARNING: pmSubtractSky(), binImage(): p_psGetStatValue() was FALSE\n");
+            }
+        }
+    }
+    psFree(binVector);
+    psFree(binMask);
+    psFree(myStats);
+
+    return(origImage);
+}
+
+/******************************************************************************
+CalculatePolyTerms(xOrder, yOrder): this routine will calculate the number of
+coefficients (or terms) in a 2-D polynomial of order (xOrder, yOrder).
+ *****************************************************************************/
+psS32 CalculatePolyTerms(psS32 xOrder, psS32 yOrder)
+{
+    psS32 maxOrder = PS_MAX(xOrder, yOrder);
+    psS32 localPolyTerms = 0;
+    psS32 order = 0;
+    psS32 num=0;
+
+    for (order=0;order<=maxOrder;order++) {
+        for (num=0;num<=order;num++) {
+            if (((order-num) <= xOrder) && (num <= yOrder)) {
+                localPolyTerms++;
+            }
+        }
+    }
+    return(localPolyTerms);
+}
+
+/******************************************************************************
+buildPolyTerms(): this routine computes a 2-D array polyTerms[][] that holds
+terms for the polynomial that is used to model the sky background.  We use
+this array primarily for convenience in computations involving sky model
+polynomials.  It is defined as:
+    polyTerms[i][0] = the power to which X is raised in the i-th term of in an
+    poly-order sky background polynomial.
+ 
+    polyTerms[i][1] = the power to which Y is raised in the i-th term of in an
+    poly-order sky background polynomial.
+ *****************************************************************************/
+psS32 **buildPolyTerms(psS32 xOrder, psS32 yOrder)
+{
+    psS32 i=0;
+    psS32 order = 0;
+    psS32 num=0;
+    psS32 localPolyTerms = CalculatePolyTerms(xOrder, yOrder);
+    psS32 maxOrder = PS_MAX(xOrder, yOrder);
+
+    // Create the data structure which we hold the xy order of each coeff.
+    psS32 **polyTerms = (psS32 **) psAlloc(localPolyTerms * sizeof(psS32 *));
+    for (i=0; i < localPolyTerms ; i++) {
+        polyTerms[i] = (psS32 *) psAlloc(2 * sizeof(psS32));
+    }
+
+    i=0;
+    // This code segment loops through each term i in the polynomial and
+    // calculates the power to which x/y are raised in that i-th term.
+    // We first do the 0-order terms, then the 1-order terms, etc.
+    for (order=0;order<=maxOrder;order++) {
+        for (num=0;num<=order;num++) {
+            if (((order-num) <= xOrder) && (num <= yOrder)) {
+                polyTerms[i][0] = order-num;
+                polyTerms[i][1] = num;
+                i++;
+            }
+        }
+    }
+
+    if (psTraceGetLevel(".psModule.pmSubtractSky.buildPolyTerms") >= 10) {
+        for (i=0; i < localPolyTerms ; i++) {
+            printf("x^%d * y^%d\n", polyTerms[i][0], polyTerms[i][1]);
+        }
+    }
+
+    return(polyTerms);
+}
+
+/******************************************************************************
+This procedure calculates various combinations of powers of x and y and stores
+them in the data structure p_psPolySums[][].  After it completes:
+ 
+    p_psPolySums[i][j] == x^i * y^j
+ 
+XXX: Use a psImage for the p_psPolySums data structure?
+XXX: Use variable size arrays for p_psPolySums[][].
+XXX: Must initialize p_psPolySums[][]?
+ *****************************************************************************/
+#define PS_MAX_POLYNOMIAL_ORDER 20
+psF64 p_psPolySums[PS_MAX_POLYNOMIAL_ORDER+1][PS_MAX_POLYNOMIAL_ORDER+1];
+void buildSums(psF64 x,
+               psF64 y,
+               psS32 xOrder,
+               psS32 yOrder)
+{
+    psS32 i = 0;
+    psS32 j = 0;
+    psF64 xSum = 0.0;
+    psF64 ySum = 0.0;
+
+    xSum = 1.0;
+    ySum = 1.0;
+    for(i=0;i<=xOrder;i++) {
+        ySum = xSum;
+        for(j=0;j<=yOrder;j++) {
+            p_psPolySums[i][j] = ySum;
+            ySum*= y;
+        }
+        xSum*= x;
+    }
+}
+
+/******************************************************************************
+ImageFitPolynomial(myPoly, dataImage, maskImage): this private routine takes
+an input image along with a mask and fits a polynomial to it.  The degree of
+the polynomial is specified by input parameter myPoly, and need not be
+symmetrical in orders of X and Y.  The polynomial must be type
+PS_POLYNOMIAL_ORD.  If there are not enough rows or columns in the input image
+for the order of the polynomial, then that order is reduced.  The algorithm
+used in this routine is based on that of the pilot project ADD, but is not
+documented anywhere.
+ *****************************************************************************/
+psPolynomial2D *ImageFitPolynomial(psPolynomial2D *myPoly,
+                                   psImage *dataImage,
+                                   psImage *maskImage)
+{
+    psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 4,
+            "---- ImageFitPolynomial() begin ----\n");
+    PS_POLY_CHECK_NULL(myPoly, NULL);
+    PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL);
+    PS_IMAGE_CHECK_NULL(dataImage, NULL);
+    PS_IMAGE_CHECK_EMPTY(dataImage, NULL);
+    PS_IMAGE_CHECK_TYPE(dataImage, PS_TYPE_F32, NULL);
+    PS_IMAGE_CHECK_NULL(maskImage, NULL);
+    PS_IMAGE_CHECK_EMPTY(maskImage, NULL);
+    PS_IMAGE_CHECK_TYPE(maskImage, PS_TYPE_U8, NULL);
+    PS_IMAGE_CHECK_SIZE_EQUAL(dataImage, maskImage, NULL);
+    psS32 oldPolyX = -1;
+    psS32 oldPolyY = -1;
+
+    // The matrix equations become singular if there are more powers of X
+    // in myPoly then there are rows of the image.  I think.  Similarly for
+    // powers of Y and columns.  So.  Here we reduce the complexity of the
+    // polynomial if there are not enough rows/columns in the input image.
+
+    if (myPoly->nX > dataImage->numRows) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.\n");
+        oldPolyX = myPoly->nX;
+        myPoly->nX = dataImage->numRows;
+    }
+    if (myPoly->nY > dataImage->numCols) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.\n");
+        oldPolyY = myPoly->nY;
+        myPoly->nY = dataImage->numCols;
+    }
+    psS32 i;
+    psS32 j;
+    psS32 x;
+    psS32 y;
+    psS32 aRow;
+    psS32 aCol;
+    // The myPoly->nX and ->nY terms are actually 1 larger
+    // than the order of the polynomial.
+    psS32 **polyTerms = buildPolyTerms(myPoly->nX-1, myPoly->nY-1);
+    // We determine how many coefficients will be in the polynomial that we
+    // are fitting to this image.
+    psS32 localPolyTerms = CalculatePolyTerms(myPoly->nX-1, myPoly->nY-1);
+    psImage *A = psImageAlloc(localPolyTerms, localPolyTerms, PS_TYPE_F64);
+    psImage *Aout = psImageAlloc(localPolyTerms, localPolyTerms, PS_TYPE_F64);
+    psVector *B = psVectorAlloc(localPolyTerms, PS_TYPE_F64);
+    psVector *outPerm = NULL;
+
+    //
+    // Initialize A matrix and B vector.
+    //
+    PS_IMAGE_SET_F64(A, 0.0);
+    PS_VECTOR_SET_F64(B, 0.0);
+
+    //
+    // We build the A matrix and B vector.
+    //
+    for (x=0;x<dataImage->numRows;x++) {
+        for (y=0;y<dataImage->numCols;y++) {
+            if (maskImage->data.U8[x][y] == 0) {
+                buildSums((psF64) x, (psF64) y, myPoly->nX-1, myPoly->nY-1);
+
+                /************************************************************
+                This code dervies from equation (7) of the pilot ADD.  However,
+                it is not exactly the same in that the order of the polynomial
+                may be different in X And Y.
+
+                Equation (7) from the pilot ADD describes 16 linear equations.
+                The i-th equation is simply the partial derivative of the
+                sky background polynomial (1) w.r.t. to the i-th term in
+                that polynomial.  The i-th equation is stored in row i of
+                matrix A[][] (matrix A[][] has origin (1,1), not (0,0)).  To
+                compute A[i][j] we simply multiply the j-th term of the Sky
+                Background Polynomial (SBP) by the i-th term of SBP.
+                ************************************************************/
+                for (aRow=0;aRow<localPolyTerms;aRow++) {
+                    for (aCol=0;aCol<localPolyTerms;aCol++) {
+                        A->data.F64[aRow][aCol]+=
+                            (p_psPolySums[ polyTerms[aCol][0] ][ polyTerms[aCol][1] ] *
+                             p_psPolySums[ polyTerms[aRow][0] ][ polyTerms[aRow][1] ]);
+                    }
+                }
+                // Build the B[] vector, which is the right-hand side of (7).
+                for (i=0;i<localPolyTerms;i++) {
+                    B->data.F64[i]+= dataImage->data.F32[x][y] *
+                                     p_psPolySums[ polyTerms[i][0] ][ polyTerms[i][1] ];
+                }
+            }
+        }
+    }
+
+    if (psTraceGetLevel(".psModule.pmSubtractSky.ImageFitPolynomial") >= 8) {
+        for (aRow=0;aRow<localPolyTerms;aRow++) {
+            for (aCol=0;aCol<localPolyTerms;aCol++) {
+                printf("A[%d][%d] is %f\n", aRow, aCol,
+                       A->data.F64[aRow][aCol]);
+            }
+        }
+
+        for (i=0;i<=localPolyTerms;i++) {
+            printf("B[%d] is %f\n", i, B->data.F64[i]);
+        }
+    }
+
+    //
+    // Solve the matrix equations for the polynomial coefficients C.
+    // XXX: How do we know if these matrix operations were successful?
+    //
+    Aout = psMatrixLUD(Aout, &outPerm, A);
+    PS_IMAGE_CHECK_NULL(Aout, NULL);
+    PS_IMAGE_CHECK_EMPTY(Aout, NULL);
+    psVector *C = psVectorAlloc(localPolyTerms, PS_TYPE_F64);
+    psMatrixLUSolve(C, Aout, B, outPerm);
+
+    //
+    // Set the appropriate coefficients in the myPoly structure.
+    //
+    for (i=0;i<localPolyTerms;i++) {
+        myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ] = C->data.F64[i];
+        psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 6,
+                "myPoly->coeff[%d][%d] is %f\n", polyTerms[i][0], polyTerms[i][1], myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ]);
+    }
+
+    //
+    // Free data structures that were allocated in this module.
+    //
+    for (i=0;i<localPolyTerms;i++) {
+        psFree(polyTerms[i]);
+    }
+    psFree(polyTerms);
+    psFree(A);
+    psFree(Aout);
+    psFree(B);
+    psFree(C);
+    psFree(outPerm);
+
+    //
+    // We restore the original size of the polynomial and set remaining
+    // coefficients to 0.0, if necessary.
+    //
+    if (oldPolyX != -1) {
+        myPoly->nX = oldPolyX;
+        for (i=oldPolyX ; i < myPoly->nX ; i++) {
+            for (j=0;j<myPoly->nY ; j++) {
+                myPoly->coeff[i][j] = 0.0;
+            }
+        }
+    }
+    if (oldPolyY != -1) {
+        myPoly->nY = oldPolyY;
+        for (i=0 ; i < myPoly->nX ; i++) {
+            for (j=oldPolyY;j<myPoly->nY ; j++) {
+                myPoly->coeff[i][j] = 0.0;
+            }
+        }
+    }
+
+    psTrace(".psModule.pmSubtractSky.ImageFitPolynomial", 4,
+            "---- ImageFitPolynomial() end successfully ----\n");
+    return(myPoly);
+}
+
+
+/******************************************************************************
+psReadout pmSubtractSky():
+ 
+XXX: use static vectors for myStats, and the binned image
+ 
+XXX: The SDR is silent about types.  PS_TYPE_F32 is implemented here.
+ *****************************************************************************/
+psReadout *pmSubtractSky(psReadout *in,
+                         void *fitSpec,
+                         psFit fit,
+                         psS32 binFactor,
+                         psStats *stats,
+                         psF32 clipSD)
+{
+    PS_READOUT_CHECK_NULL(in, NULL);
+    PS_READOUT_CHECK_EMPTY(in, NULL);
+    PS_READOUT_CHECK_TYPE(in, PS_TYPE_F32, NULL);
+    psTrace(".psModule.pmSubtractSky", 4,
+            "---- pmSubtractSky() begin ----\n");
+
+    if ((fit != PM_FIT_NONE) &&
+            (fit != PM_FIT_POLYNOMIAL) &&
+            (fit != PM_FIT_SPLINE)) {
+        psError(PS_ERR_UNKNOWN, true, "psFit is unallowable (%d).  Returning in image.\n", fit);
+        return(in);
+    }
+
+    psStatsOptions statOptions = 0;
+
+    //
+    // Return the original input readout if the fit specs are poorly defined.
+    // No warning or error messages should be generated.
+    //
+    if ((fitSpec == NULL) ||
+            ((fit == PM_FIT_NONE) || (fit == PM_FIT_SPLINE))) {
+        //        psLogMsg(__func__, PS_LOG_WARN, "Fit specs are poorly defined.  Returning in image.\n");
+        return(in);
+    }
+    psImage *origImage = in->image;
+    psImage *binnedImage = NULL;
+    psPolynomial2D *myPoly = NULL;
+    psImage *binnedMaskImage = NULL;
+    psU32 oldStatOptions = 0;
+
+    //
+    // Determine which statistic to use when binning pixels, if any.
+    //
+    if (stats != NULL) {
+        statOptions = stats->options;
+        if (1 < p_psDetermineNumBits(statOptions)) {
+            psLogMsg(__func__, PS_LOG_WARN, "WARNING: Multiple statistical options have been requested.\n");
+            statOptions = getHighestPriorityStatOption(statOptions);
+            if (statOptions == -1) {
+                psError(PS_ERR_UNKNOWN, true, "Not allowable stats->option was specified.  Returning in image.\n");
+                return(in);
+            }
+            // Save old input "stats" parameter.
+            oldStatOptions = stats->options;
+            stats->options = statOptions;
+        }
+        if (0 == p_psDetermineNumBits(statOptions)) {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractSky(): no stats->options was requested\n");
+        }
+    }
+
+    //
+    // Generate required warning messages.
+    //
+    if (binFactor <= 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): binFactor is %d\n", binFactor);
+    }
+    if (stats == NULL) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): input parameter stats is NULL\n");
+    }
+
+    //
+    // Bin the input image according to input parameters.
+    // Create a new binned image mask.
+    //
+    if ((binFactor <= 1) || (stats == NULL) || (0 == p_psDetermineNumBits(statOptions))) {
+        // No binning is required here.  Simply create a copy of the image
+        // and a mask.
+        binnedImage = psImageCopy(binnedImage, origImage, PS_TYPE_F32);
+        if (binnedImage == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageCopy() returned NULL.  Returning in image.\n");
+            return(in);
+        }
+
+        if (in->mask != NULL) {
+            binnedMaskImage = psImageCopy(binnedMaskImage, in->mask, PS_TYPE_U8);
+            if (binnedMaskImage == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageCopy() returned NULL.  Returning in image.\n");
+                psFree(binnedImage);
+                return(in);
+            }
+        } else {
+            binnedMaskImage = psImageAlloc(binnedImage->numCols,
+                                           binnedImage->numRows,
+                                           PS_TYPE_U8);
+            PS_IMAGE_SET_U8(binnedMaskImage, 0);
+        }
+    } else {
+        binnedImage = psImageRebin(NULL, origImage, in->mask, 0, binFactor, stats);
+        if (binnedImage == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageRebin() returned NULL.  Returning in image.\n");
+            return(in);
+        }
+        binnedMaskImage = psImageAlloc(binnedImage->numCols,
+                                       binnedImage->numRows,
+                                       PS_TYPE_U8);
+        PS_IMAGE_SET_U8(binnedMaskImage, 0);
+    }
+    psTrace(".psModule.pmSubtractSky", 4,
+            "binnedImage size is (%d, %d)\n", binnedImage->numRows, binnedImage->numCols);
+
+    //
+    // Clip pixels that are outside the acceptable range.
+    //
+    if (clipSD <= 0.0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD);
+    } else {
+        // Determine the mean and standard deviation of the binned image.
+        psF64 binnedMean;
+        psF64 binnedStdev;
+        psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        psStats *rc =  psImageStats(myStats, binnedImage, NULL, 0);
+        if (rc == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        if (false == p_psGetStatValue(rc, &binnedMean)) {
+            psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        psTrace(".psModule.pmSubtractSky", 6,
+                "binned Mean is %f\n", binnedMean);
+
+        myStats->options = PS_STAT_SAMPLE_STDEV;
+        rc =  psImageStats(myStats, binnedImage, NULL, 0);
+        if (rc == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "psImageStats(): could not perform requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        if (false == p_psGetStatValue(myStats, &binnedStdev)) {
+            psError(PS_ERR_UNKNOWN, false, "p_psGetStatValue(): could not determine requested statistical operation.  Returning in image.\n");
+            return(in);
+        }
+        psFree(myStats);
+        psTrace(".psModule.pmSubtractSky", 6,
+                "binned StDev is %f\n", binnedStdev);
+
+        // Clip all pixels which are more than clipSD sigmas from the mean.
+        psTrace(".psModule.pmSubtractSky", 6,
+                "clipSD is %f\n", clipSD);
+
+        for (psS32 row = 0; row < binnedImage->numRows ; row++) {
+            for (psS32 col = 0; col < binnedImage->numCols ; col++) {
+                if (fabs(binnedImage->data.F32[row][col] - binnedMean) >
+                        (clipSD * binnedStdev)) {
+                    binnedMaskImage->data.U8[row][col] = 1;
+                }
+            }
+        }
+    }
+
+    //
+    // Fit the polynomial to the binned image
+    //
+    if (fit == PM_FIT_POLYNOMIAL) {
+        myPoly = (psPolynomial2D *) fitSpec;
+        PS_POLY_CHECK_NULL(myPoly, NULL);
+        PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL);
+
+        myPoly = ImageFitPolynomial(myPoly, binnedImage, binnedMaskImage);
+
+        if (myPoly != NULL) {
+            // Set the pixels in the binned image to that of the polynomial.
+            binnedImage = psImageEvalPolynomial(binnedImage, myPoly);
+            if (binnedImage == NULL) {
+                psError(PS_ERR_UNKNOWN, false, "psImageEvalPolynomial() returned NULL.  Returning in image.\n");
+                psFree(binnedMaskImage);
+                if (!((binFactor <= 1) || (stats == NULL))) {
+                    psFree(binnedImage);
+                }
+                if (oldStatOptions != 0) {
+                    stats->options = statOptions;
+                }
+                return(in);
+            }
+        } else {
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: pmSubtractSky(): could not model sky with a polynomial.\n");
+            psFree(binnedMaskImage);
+            if (!((binFactor <= 1) || (stats == NULL))) {
+                psFree(binnedImage);
+            }
+            if (oldStatOptions != 0) {
+                stats->options = statOptions;
+            }
+            return(in);
+        }
+    } else {
+        // We shouldn't get here since we check this above.
+        psError(PS_ERR_UNKNOWN, true, "Unallowable fit type.  Returning in image.\n");
+        psFree(binnedMaskImage);
+        if (!((binFactor <= 1) || (stats == NULL))) {
+            psFree(binnedImage);
+        }
+        if (oldStatOptions != 0) {
+            stats->options = statOptions;
+        }
+        return(in);
+    }
+
+    //
+    //Subtract the polynomially fitted image from the original image
+    //
+    if (binFactor <= 1) {
+        // The binned image is the same size as the original image.
+        for (psS32 row = 0; row < origImage->numRows ; row++) {
+            for (psS32 col = 0; col < origImage->numCols ; col++) {
+                origImage->data.F32[row][col]-= binnedImage->data.F32[row][col];
+            }
+        }
+    } else {
+        for (psS32 row = 0; row < origImage->numRows ; row++) {
+            for (psS32 col = 0; col < origImage->numCols ; col++) {
+                // We calculate the F32 value of the pixel coordinates in the
+                // binned image and then use a pixel interpolation routine to
+                // determine the value of the pixel at that location.
+                psF32 binRowF64 = ((psF32) row) / ((psF32) binFactor);
+                psF32 binColF64 = ((psF32) col) / ((psF32) binFactor);
+
+                // We add 0.5 to the pixel locations since the pixel
+                // interpolation routine defines the location of pixel
+                // (i, j) as (i+0.5, j+0.5).
+                binRowF64+= 0.5;
+                binColF64+= 0.5;
+
+                psF32 binPixel = (psF32) psImagePixelInterpolate(
+                                     binnedImage, binColF64, binRowF64,
+                                     NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+                origImage->data.F32[row][col]-= binPixel;
+
+                psTrace(".psModule.pmSubtractSky", 8,
+                        "image[%d][%d] <--> binnedImage[%.2f][%.2f]: %f\n",
+                        row, col, binRowF64-0.5, binColF64-0.5, binPixel);
+            }
+        }
+
+    }
+    psFree(binnedMaskImage);
+    psFree(binnedImage);
+    if (oldStatOptions != 0) {
+        stats->options = statOptions;
+    }
+
+    psTrace(".psModule.pmSubtractSky", 4,
+            "---- pmSubtractSky() exit successfully ----\n");
+    return(in);
+}
Index: /branches/rel4/psModules/src/pmSubtractSky.h
===================================================================
--- /branches/rel4/psModules/src/pmSubtractSky.h	(revision 3057)
+++ /branches/rel4/psModules/src/pmSubtractSky.h	(revision 3057)
@@ -0,0 +1,41 @@
+/** @file  pmSubtractSky.h
+ *
+ *  This file will contain a module which will create a model of the
+ *  background sky and subtract that from the input image.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-18 02:27:42 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_SUBTRACT_SKY_H)
+#define PM_SUBTRACT_SKY_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"
+
+// XXX: this is pmFit in pmSubtractBias.c, named psFit here.
+typedef enum {
+    PM_FIT_NONE,                              ///< No fit
+    PM_FIT_POLYNOMIAL,                        ///< Fit polynomial
+    PM_FIT_SPLINE                             ///< Fit cubic splines
+} psFit;
+
+psReadout *pmSubtractSky(psReadout *in,
+                         void *fitSpec,
+                         psFit fit,
+                         int binFactor,
+                         psStats *stats,
+                         float clipSD);
+#endif
Index: /branches/rel4/psModules/src/psErrorCodes.dat
===================================================================
--- /branches/rel4/psModules/src/psErrorCodes.dat	(revision 3057)
+++ /branches/rel4/psModules/src/psErrorCodes.dat	(revision 3057)
@@ -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/rel4/psModules/src/psTest.c
===================================================================
--- /branches/rel4/psModules/src/psTest.c	(revision 3057)
+++ /branches/rel4/psModules/src/psTest.c	(revision 3057)
@@ -0,0 +1,245 @@
+//
+// 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"
+
+psBool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,
+                       testDescription tests[], psS32 argc, char * const argv[] )
+{
+    psBool success = true;
+    psBool runAll = true;
+    psBool useFork = true;
+    psBool found;
+    psS32 c;
+    psS32 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 ( psS32 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 ( psS32 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(PS_ERR_UNKNOWN, true, "Failed to parse the testpoint number (%s).",
+                            optarg );
+                    break;
+                }
+                found = false;
+                for ( psS32 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(PS_ERR_UNKNOWN, true, "The specified testpoint number (%d) doesn't exist in this test driver.",
+                            n );
+                    break;
+                }
+                break;
+            case '?':
+                psError(PS_ERR_UNKNOWN, true, "Option %s is not recognized and is ignored.", optarg );
+                break;
+            }
+        }
+    }
+
+    if ( runAll ) {
+        for ( psS32 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( PS_ERR_UNKNOWN, true,
+                 "One or more tests failed" );
+    }
+
+    return success;
+}
+
+psBool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+                  testFcn fcn, psS32 expectedReturn, psBool useFork )
+{
+    psS32 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
+            psS32 currentId = psMemGetId();
+            psS32 retVal = fcn();
+            if ( retVal == 0 ) { // only bother checking memory if test executed to end.
+                if ( psMemCheckLeaks( currentId, NULL, stderr, false ) != 0 ) {
+                    psError(PS_ERR_UNKNOWN, true, "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 {
+        psS32 currentId = psMemGetId();
+        childReturn = fcn();
+        if ( childReturn == 0 ) { // only bother checking memory if test executed to end.
+            if ( psMemCheckLeaks( currentId, NULL, stderr, false ) != 0 ) {
+                psError(PS_ERR_UNKNOWN, true, "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,
+                                psS32 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,
+                    psBool 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/rel4/psModules/src/psTest.h
===================================================================
--- /branches/rel4/psModules/src/psTest.h	(revision 3057)
+++ /branches/rel4/psModules/src/psTest.h	(revision 3057)
@@ -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/rel4/psModules/templates/c
===================================================================
--- /branches/rel4/psModules/templates/c	(revision 3057)
+++ /branches/rel4/psModules/templates/c	(revision 3057)
@@ -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/rel4/psModules/templates/h
===================================================================
--- /branches/rel4/psModules/templates/h	(revision 3057)
+++ /branches/rel4/psModules/templates/h	(revision 3057)
@@ -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/rel4/psModules/test/.cvsignore
===================================================================
--- /branches/rel4/psModules/test/.cvsignore	(revision 3057)
+++ /branches/rel4/psModules/test/.cvsignore	(revision 3057)
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+tst_pmFlatField
+tst_pmMaskBadPixels
+tst_pmNonLinear
+tst_pmSubtractBias
+temp
Index: /branches/rel4/psModules/test/FullUnitTest
===================================================================
--- /branches/rel4/psModules/test/FullUnitTest	(revision 3057)
+++ /branches/rel4/psModules/test/FullUnitTest	(revision 3057)
@@ -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/rel4/psModules/test/Makefile.am
===================================================================
--- /branches/rel4/psModules/test/Makefile.am	(revision 3057)
+++ /branches/rel4/psModules/test/Makefile.am	(revision 3057)
@@ -0,0 +1,19 @@
+bin_PROGRAMS = tst_pmFlatField tst_pmMaskBadPixels tst_pmNonLinear tst_pmSubtractBias tst_pmReadoutCombine tst_pmSubtractSky
+
+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
+
+tst_pmReadoutCombine_SOURCES = tst_pmReadoutCombine.c
+tst_pmReadoutCombine_LDFLAGS = -L../src -lpsmodule
+
+tst_pmSubtractSky_SOURCES = tst_pmSubtractSky.c
+tst_pmSubtractSky_LDFLAGS = -L../src -lpsmodule
Index: /branches/rel4/psModules/test/Makefile.in
===================================================================
--- /branches/rel4/psModules/test/Makefile.in	(revision 3057)
+++ /branches/rel4/psModules/test/Makefile.in	(revision 3057)
@@ -0,0 +1,498 @@
+# Makefile.in generated by automake 1.9.2 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_pmReadoutCombine_SOURCES) $(tst_pmSubtractBias_SOURCES) $(tst_pmSubtractSky_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 = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = tst_pmFlatField$(EXEEXT) tst_pmMaskBadPixels$(EXEEXT) \
+	tst_pmNonLinear$(EXEEXT) tst_pmSubtractBias$(EXEEXT) \
+	tst_pmReadoutCombine$(EXEEXT) tst_pmSubtractSky$(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_pmReadoutCombine_OBJECTS = tst_pmReadoutCombine.$(OBJEXT)
+tst_pmReadoutCombine_OBJECTS = $(am_tst_pmReadoutCombine_OBJECTS)
+tst_pmReadoutCombine_LDADD = $(LDADD)
+am_tst_pmSubtractBias_OBJECTS = tst_pmSubtractBias.$(OBJEXT)
+tst_pmSubtractBias_OBJECTS = $(am_tst_pmSubtractBias_OBJECTS)
+tst_pmSubtractBias_LDADD = $(LDADD)
+am_tst_pmSubtractSky_OBJECTS = tst_pmSubtractSky.$(OBJEXT)
+tst_pmSubtractSky_OBJECTS = $(am_tst_pmSubtractSky_OBJECTS)
+tst_pmSubtractSky_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(tst_pmFlatField_SOURCES) $(tst_pmMaskBadPixels_SOURCES) \
+	$(tst_pmNonLinear_SOURCES) $(tst_pmReadoutCombine_SOURCES) \
+	$(tst_pmSubtractBias_SOURCES) $(tst_pmSubtractSky_SOURCES)
+DIST_SOURCES = $(tst_pmFlatField_SOURCES) \
+	$(tst_pmMaskBadPixels_SOURCES) $(tst_pmNonLinear_SOURCES) \
+	$(tst_pmReadoutCombine_SOURCES) $(tst_pmSubtractBias_SOURCES) \
+	$(tst_pmSubtractSky_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@
+am__tar = @am__tar@
+am__untar = @am__untar@
+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
+tst_pmReadoutCombine_SOURCES = tst_pmReadoutCombine.c
+tst_pmReadoutCombine_LDFLAGS = -L../src -lpsmodule
+tst_pmSubtractSky_SOURCES = tst_pmSubtractSky.c
+tst_pmSubtractSky_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_pmReadoutCombine$(EXEEXT): $(tst_pmReadoutCombine_OBJECTS) $(tst_pmReadoutCombine_DEPENDENCIES) 
+	@rm -f tst_pmReadoutCombine$(EXEEXT)
+	$(LINK) $(tst_pmReadoutCombine_LDFLAGS) $(tst_pmReadoutCombine_OBJECTS) $(tst_pmReadoutCombine_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)
+tst_pmSubtractSky$(EXEEXT): $(tst_pmSubtractSky_OBJECTS) $(tst_pmSubtractSky_DEPENDENCIES) 
+	@rm -f tst_pmSubtractSky$(EXEEXT)
+	$(LINK) $(tst_pmSubtractSky_LDFLAGS) $(tst_pmSubtractSky_OBJECTS) $(tst_pmSubtractSky_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_pmReadoutCombine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmSubtractBias.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmSubtractSky.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@	DEPDIR=$(DEPDIR) $(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@	DEPDIR=$(DEPDIR) $(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@	DEPDIR=$(DEPDIR) $(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; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+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:
+	-test -z "$(CONFIG_CLEAN_FILES)" || 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/rel4/psModules/test/runTest
===================================================================
--- /branches/rel4/psModules/test/runTest	(revision 3057)
+++ /branches/rel4/psModules/test/runTest	(revision 3057)
@@ -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/rel4/psModules/test/tst_pmFlatField.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmFlatField.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmFlatField.c	(revision 3057)
@@ -0,0 +1,278 @@
+/** @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.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 01:17: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, 753, "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();
+    inReadout->image = inImage;
+    PRINT_MATRIX(inImage,F64,"Input image:");
+    CREATE_AND_SET_IMAGE(flatImage1,F64,2.0,3,3)
+    psReadout *flatReadout = psReadoutAlloc();
+    flatReadout->image = flatImage1;
+    PRINT_MATRIX(flatImage1,F64,"Flat image:");
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test A - Returned false should be true");
+        return 1;
+    }
+    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;
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test B - Returned false should be true");
+        return 2;
+    }
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA, "Resulting mask:");
+    PRINT_MATRIX(inImage,F64,"Resulting image:");
+    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] = 3.0;
+    flatImage2->data.F64[0][1] = -3.0;
+    PRINT_MATRIX(flatImage2, F64, "Flat image:");
+    CREATE_AND_SET_IMAGE(mask1,U8,0,3,3);
+    psFree(inReadout->mask);
+    inReadout->mask = mask1;
+    if ( !pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test C - Returned false should be true");
+        return 3;
+    }
+    PRINT_MATRIX(flatImage2, F64, "Flat image out:");
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA,"Resulting mask:");
+    PRINT_MATRIX(inImage,F64,"Resulting image:");
+    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);
+    if( pmFlatField(inReadout, NULL) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test D - Returned true should be false");
+        return 4;
+    }
+    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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test E - Returned true should be false" );
+        return 5;
+    }
+    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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test F - Returned true should be false" );
+        return 6;
+    }
+    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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test G - Returned true should be false");
+        return 7;
+    }
+    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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test H - Returned true should be false");
+        return 8;
+    }
+    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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test I - Returned true should be false");
+        return 9;
+    }
+    *(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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test J - Returned true should be false");
+        return 10;
+    }
+    *(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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test K - Returned ture should be false");
+        return 11;
+    }
+    *(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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test L - Returned true should be false");
+        return 12;
+    }
+    *(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;
+    if ( pmFlatField(inReadout, flatReadout) ) {
+        psError(PS_ERR_UNKNOWN,true,"Test M - Returned true should be false");
+        return 13;
+    }
+    *(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/rel4/psModules/test/tst_pmMaskBadPixels.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmMaskBadPixels.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmMaskBadPixels.c	(revision 3057)
@@ -0,0 +1,280 @@
+/** @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.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 01:30:16 $
+ *
+ *  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);
+    psReadout *inReadout = psReadoutAlloc();
+    inReadout->image = 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);
+
+    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);
+    psReadout *inReadout2 = psReadoutAlloc();
+    inReadout2->image = 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);
+
+    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);
+    psReadout *inReadout3 = psReadoutAlloc();
+    inReadout3->image = 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);
+
+    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);
+    psReadout *inReadout4 = psReadoutAlloc();
+    inReadout4->image = 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);
+
+    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);
+    psReadout *inReadout5 = psReadoutAlloc();
+    inReadout5->image = inImage5;
+    pmMaskBadPixels(inReadout5, NULL, 0, 100.0, 1, 10);
+    psFree(inReadout5);
+
+    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);
+    psReadout *inReadout6 = psReadoutAlloc();
+    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);
+    psReadout *inReadout7 = psReadoutAlloc();
+    inReadout7->image = inImage7;
+    inReadout7->mask = mask7i;
+    pmMaskBadPixels(inReadout7, mask7, 0, 100.0, 1, 10);
+    psFree(mask7);
+    psFree(inReadout7);
+
+    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);
+    psReadout *inReadout8 = psReadoutAlloc();
+    inReadout8->image = inImage8;
+    inReadout8->mask = mask8i;
+    pmMaskBadPixels(inReadout8, mask8, 0, 100.0, 1, 10);
+    psFree(mask8);
+    psFree(inReadout8);
+
+    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);
+    psReadout *inReadout9 = psReadoutAlloc();
+    inReadout9->image = inImage9;
+    inReadout9->mask = mask9i;
+    *(int*)&inReadout9->col0 = 150;
+    *(int*)&inReadout9->row0 = 150;
+    pmMaskBadPixels(inReadout9, mask9, 0, 100.0, 1, 10);
+    psFree(mask9);
+    psFree(inReadout9);
+
+    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);
+    psReadout *inReadout10 = psReadoutAlloc();
+    inReadout10->image = inImage10;
+    inReadout10->mask = mask10i;
+    pmMaskBadPixels(inReadout10, mask10, 0, 100.0, 1, 10);
+    psFree(mask10);
+    psFree(inReadout10);
+
+    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);
+    psReadout *inReadout11 = psReadoutAlloc();
+    inReadout11->image = inImage11;
+    inReadout11->mask = mask11i;
+    pmMaskBadPixels(inReadout11, mask11, 0, 100.0, 1, 10);
+    psFree(mask11);
+    psFree(inReadout11);
+
+    return 0;
+}
+
Index: /branches/rel4/psModules/test/tst_pmNonLinear.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmNonLinear.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmNonLinear.c	(revision 3057)
@@ -0,0 +1,510 @@
+/** @file tst_pmNonLinear.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)].  
+ *
+ * test02, test03: This code tests the functions with various unallowable
+ * input parameters (NULLS) and incorrect vector sizes.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-11 23:39:41 $
+ *
+ *  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);
+static int test02(void);
+static int test03(void);
+testDescription tests[] = {
+                              {test00, 000, "pmNonLinearityPolynomial", true, false},
+                              {test01, 000, "pmNonLinearityLookup", true, false},
+                              {test02, 000, "pmNonLinearityPolynomial(): error/warning conditions", true, false},
+                              {test03, 000, "pmNonLinearityLookup(): error/warning conditions", true, 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 = true;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = myImage;
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    myPoly->coeff[1] = 1.0;
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "doNonLinearityPolynomialTest");
+
+    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(myPoly, (float) (i + j));
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myPoly);
+    printFooter(stdout, "pmNonLinear", "doNonLinearityPolynomialTest", true);
+    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 = true;
+    int tableSize = PS_MAX(numCols, numRows)*2;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = myImage;
+    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "doNonLinearityLookupTest");
+    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("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(in);
+    psFree(out);
+    printFooter(stdout, "pmNonLinear", "doNonLinearityLookupTest", true);
+    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);
+}
+
+int test02( void )
+{
+    int i;
+    int j;
+    int testStatus = true;
+    psImage *myImage = psImageAlloc(NUM_COLS, NUM_ROWS, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *rc = NULL;
+    myReadout->image = myImage;
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    myPoly->coeff[1] = 1.0;
+
+    printPositiveTestHeader(stdout, "pmNonLinear", "Testing bad input parameter conditions.");
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL input readout.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityPolynomial(NULL, myPoly);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL input readout->image.  Should generate error, return NULL.\n");
+    psImage *tmpImage = myReadout->image;
+    myReadout->image = NULL;
+    rc = pmNonLinearityPolynomial(myReadout, myPoly);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImage;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityPolynomial() with NULL polynomial.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityPolynomial(myReadout, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    psFree(myReadout);
+    psFree(myPoly);
+    return(testStatus);
+}
+
+
+int test03Init(psReadout *myReadout)
+{
+    for (psS32 i=0;i<NUM_ROWS;i++) {
+        for (psS32 j=0;j<NUM_COLS;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+    return(0);
+}
+
+int test03()
+{
+    int i;
+    int j;
+    int testStatus = true;
+    int tableSize = PS_MAX(NUM_COLS, NUM_ROWS)*3;
+    psImage *myImage = psImageAlloc(NUM_COLS, NUM_ROWS, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *rc = NULL;
+    myReadout->image = myImage;
+    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *inOne = psVectorAlloc(1, PS_TYPE_F32);
+    psVector *inSmall = psVectorAlloc(tableSize-1, PS_TYPE_F32);
+    psVector *inBig = psVectorAlloc(tableSize+1, PS_TYPE_F32);
+    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *outOne = psVectorAlloc(1, PS_TYPE_F32);
+    psVector *outSmall = psVectorAlloc(tableSize-1, PS_TYPE_F32);
+    psVector *outBig = psVectorAlloc(tableSize+1, PS_TYPE_F32);
+
+    test03Init(myReadout);
+    for (i=0;i<tableSize;i++) {
+        in->data.F32[i] = (float) i;
+        out->data.F32[i] = (float) (2 * i);
+        inBig->data.F32[i] = (float) i;
+        outBig->data.F32[i] = (float) (2 * i);
+        if (i < tableSize-1) {
+            inSmall->data.F32[i] = (float) i;
+            outSmall->data.F32[i] = (float) (2 * i);
+        }
+    }
+    inBig->data.F32[tableSize] = (float) tableSize;
+    outBig->data.F32[tableSize] = (float) (2 * tableSize);
+    inOne->data.F32[0] = 0.0;
+    outOne->data.F32[0] = 0.0;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL input psReadout.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(NULL, in, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL input psReadout->image.  Should generate error, return NULL.\n");
+    psImage *tmpImage = myReadout->image;
+    myReadout->image = NULL;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImage;
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL inFlux psVector.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(myReadout, NULL, out);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with NULL outFlux psVector.  Should generate error, return NULL.\n");
+    rc = pmNonLinearityLookup(myReadout, in, NULL);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, in, outBig);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, in, outSmall);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inSmall, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inBig, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inSmall, outBig);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.\n");
+    rc = pmNonLinearityLookup(myReadout, inBig, outSmall);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with inFlux psVector size 1.  Should generate error, return original psReadout.\n");
+    rc = pmNonLinearityLookup(myReadout, inOne, out);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() did not return the original psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) ((i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.\n");
+    test03Init(myReadout);
+    myReadout->image->data.F32[0][0] = -1;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if(i==0 && j==0) {
+                if(actual != 0.0) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n",i,j,actual,0.0);
+                }
+            } else {
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = false;
+                }
+            }
+        }
+    }
+
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.\n");
+    test03Init(myReadout);
+    myReadout->image->data.F32[NUM_ROWS-1][NUM_COLS-1] = 100;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            psF32 actual = rc->image->data.F32[i][j];
+            if(i==(NUM_ROWS-1) && j==(NUM_COLS-1)) {
+                if(actual != (tableSize-1)*2) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n",i,j,actual,(tableSize-1)*2.0);
+                }
+            } else {
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = false;
+                }
+            }
+        }
+    }
+
+    test03Init(myReadout);
+    printf("------------------------------------------------------------\n");
+    printf("Calling pmNonLinearityLookup() with image values not in vector.\n");
+    myReadout->image->data.F32[0][0] = 0.5;
+    rc = pmNonLinearityLookup(myReadout, in, out);
+    if (rc == NULL) {
+        printf("TEST ERROR: pmNonLinearityPolynomial() returned a NULL psReadout\n");
+        testStatus = false;
+    }
+    for (i=0;i<NUM_ROWS;i++) {
+        for (j=0;j<NUM_COLS;j++) {
+            psF32 expect = (float) (2 * (i + j));
+            if(i==0 && j==0) {
+                expect = 1.0;
+            }
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = false;
+            }
+        }
+    }
+
+    psFree(myReadout);
+    psFree(in);
+    psFree(inOne);
+    psFree(inSmall);
+    psFree(inBig);
+    psFree(out);
+    psFree(outOne);
+    psFree(outSmall);
+    psFree(outBig);
+
+    printFooter(stdout, "pmNonLinear", "Testing bad input parameter conditions.", true);
+    return(testStatus);
+}
Index: /branches/rel4/psModules/test/tst_pmReadoutCombine.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmReadoutCombine.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmReadoutCombine.c	(revision 3057)
@@ -0,0 +1,451 @@
+/** @file tst_pmReadoutCombine.c
+ *
+ *  test00() This routine will test the basic functionality.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-10 22:22:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: Untested:
+ * S16, S32 types
+ * Multiple input readouts with varying sizes and offsets.
+ * params->fracLow and params->fracHigh
+ * params->nKeep
+ * (gain > 0.0) && (readnoise >= 0.0) (applyZeroScale == true)
+ * (gain > 0.0) && (readnoise >= 0.0) (applyZeroScale == false)
+ *
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmReadoutCombine.h"
+static int test00(void);
+static int test01(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias(): input parameter error conditions", 0, false},
+                              {NULL}
+                          };
+
+#define NUM_READOUTS  10
+#define INPUT_NUM_ROWS 20
+#define INPUT_NUM_COLS 20
+#define VEC_ZERO 1.0
+#define VEC_SCALE 2.0
+
+psS32 VerifyTheOutput(psImage *output, psF32 expect)
+{
+    bool testStatus = true;
+
+    for (psS32 i = 0 ; i < output->numRows ; i++) {
+        for (psS32 j = 0 ; j < output->numCols ; j++) {
+            if (output->data.F32[i][j] != expect) {
+                printf("TEST ERROR: output[%d][%d] is %.2f, should be %f\n", i, j, output->data.F32[i][j], expect);
+                testStatus = false;
+            }
+        }
+    }
+    return(testStatus);
+}
+
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+/******************************************************************************
+simpleCombineNoOverlap(): this routine creates a list of NUM_READOUTS input
+readouts and calls pmReadoutCombine().
+ *****************************************************************************/
+
+int simpleCombineNoOverlap(psS32 numInputCols, psS32 numInputRows)
+{
+    int i;
+    int r;
+    psList *list = NULL;
+    int baseRowsReadout[NUM_READOUTS];
+    int baseColsReadout[NUM_READOUTS];
+    int baseRows[NUM_READOUTS];
+    int baseCols[NUM_READOUTS];
+    int numRows[NUM_READOUTS];
+    int numCols[NUM_READOUTS];
+    int minOutRow = 10000;
+    int minOutCol = 10000;
+    int maxOutRow = -1;
+    int maxOutCol = -1;
+    psImage *output = NULL;
+    psCombineParams *params = (psCombineParams *) psAlloc(sizeof(psCombineParams));
+    psVector *zero = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *scale = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    printPositiveTestHeader(stdout, "pmReadoutCombine", "simpleCombineNoOverlap");
+
+    for (i=0;i<NUM_READOUTS;i++) {
+        zero->data.F32[i] = VEC_ZERO;
+    }
+    for (i=0;i<NUM_READOUTS;i++) {
+        scale->data.F32[i] = VEC_SCALE;
+    }
+
+    params->stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    params->maskVal = 1;
+    params->fracLow = 0.0;
+    params->fracHigh = 10000.0;
+    params->nKeep = 0;
+
+    for (r=0;r<NUM_READOUTS;r++) {
+        baseRowsReadout[r] = r + 40;
+        baseColsReadout[r] = r + 42;
+        baseRows[r] = r;
+        baseCols[r] = r+2;
+        numRows[r] = 4 + (2 * r);
+        numCols[r] = 8 + (2 * r);
+
+        baseRowsReadout[r] = 0;
+        baseColsReadout[r] = 0;
+        baseRows[r] = 0;
+        baseCols[r] = 0;
+        numRows[r] = numInputRows;
+        numCols[r] = numInputCols;
+
+        psImage *tmpImage = psImageAlloc(numCols[r], numRows[r], PS_TYPE_F32);
+        PS_IMAGE_SET_F32(tmpImage, ((float) r));
+        *(int *) (& (tmpImage->row0)) = baseRows[r];
+        *(int *) (& (tmpImage->col0)) = baseCols[r];
+        /*
+                psReadout *tmpReadout = psReadoutAlloc(baseColsReadout[r],
+                                                       baseRowsReadout[r],
+                                                       tmpImage);
+        */
+        psReadout *tmpReadout = psReadoutAlloc();
+        tmpReadout->image = tmpImage;
+
+        minOutRow = PS_MIN(minOutRow, (baseRowsReadout[r] + baseRows[r]));
+        minOutCol = PS_MIN(minOutCol, (baseColsReadout[r] + baseCols[r]));
+        maxOutRow = PS_MAX(maxOutRow, (baseRowsReadout[r] + baseRows[r] + numRows[r]));
+        maxOutCol = PS_MAX(maxOutCol, (baseColsReadout[r] + baseCols[r] + numCols[r]));
+
+        if (r == 0) {
+            list = psListAlloc(tmpReadout);
+        } else {
+            psListAdd(list, PS_LIST_HEAD, tmpReadout);
+        }
+    }
+    printf("tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (%d, %d) (%d, %d)\n",
+           minOutRow, minOutCol, maxOutRow, maxOutCol);
+
+    output = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    psF32 NR = (psF32) NUM_READOUTS;
+    //    psF32 expectedPixel = ((((NR-1.0) * (NR/2.0)) / NR) + VEC_ZERO) * VEC_SCALE;
+    psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+    VerifyTheOutput(output, expectedPixel);
+
+    psFree(params->stats);
+    psFree(params);
+    psFree(output);
+    psFree(zero);
+    psFree(scale);
+
+    psListElem *tmpInput = (psListElem *) list->head;
+    while (NULL != tmpInput) {
+        psReadout *tmpReadout = (psReadout *) tmpInput->data;
+        psFree(tmpReadout);
+        tmpInput = tmpInput->next;
+    }
+    psFree(list);
+
+    printFooter(stdout, "pmReadoutCombine", "simpleCombineNoOverlap", true);
+    return(0);
+}
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= simpleCombineNoOverlap(1, 1);
+    testStatus |= simpleCombineNoOverlap(INPUT_NUM_COLS, 1);
+    testStatus |= simpleCombineNoOverlap(1, INPUT_NUM_ROWS);
+    testStatus |= simpleCombineNoOverlap(INPUT_NUM_COLS, INPUT_NUM_ROWS);
+
+    return(testStatus);
+}
+
+int test01()
+{
+    int i;
+    int r;
+    psList *list = NULL;
+    int baseRowsReadout[NUM_READOUTS];
+    int baseColsReadout[NUM_READOUTS];
+    int baseRows[NUM_READOUTS];
+    int baseCols[NUM_READOUTS];
+    int numRows[NUM_READOUTS];
+    int numCols[NUM_READOUTS];
+    int minOutRow = 10000;
+    int minOutCol = 10000;
+    int maxOutRow = -1;
+    int maxOutCol = -1;
+    psImage *output = NULL;
+    psImage *rc = NULL;
+    psCombineParams *params = (psCombineParams *) psAlloc(sizeof(psCombineParams));
+    psVector *zero = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *zeroHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *zeroBig = psVectorAlloc(NUM_READOUTS+1, PS_TYPE_F32);
+    psVector *zeroF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    psVector *scale = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *scaleHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *scaleBig = psVectorAlloc(NUM_READOUTS*2, PS_TYPE_F32);
+    psVector *scaleF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    int testStatus = true;
+    for (i=0;i<NUM_READOUTS;i++) {
+        zero->data.F32[i] = 3.0;
+        zeroBig->data.F32[i] = 3.0;
+        zero->data.F32[i] = VEC_ZERO;
+        zeroBig->data.F32[i] = VEC_ZERO;
+    }
+    for (i=0;i<NUM_READOUTS;i++) {
+        scale->data.F32[i] = 6.0;
+        scaleBig->data.F32[i] = 6.0;
+        scale->data.F32[i] = VEC_SCALE;
+        scaleBig->data.F32[i] = VEC_SCALE;
+    }
+    printPositiveTestHeader(stdout, "pmReadoutCombine", "Testing bad input parameter conditions");
+
+    params->stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    params->maskVal = 1;
+    params->fracLow = 0.0;
+    params->fracHigh = 10000.0;
+    params->nKeep = 0;
+
+    for (r=0;r<NUM_READOUTS;r++) {
+        baseRowsReadout[r] = 0;
+        baseColsReadout[r] = 0;
+        baseRows[r] = 0;
+        baseCols[r] = 0;
+        numRows[r] = INPUT_NUM_ROWS;
+        numCols[r] = INPUT_NUM_COLS;
+
+        psImage *tmpImage = psImageAlloc(numCols[r], numRows[r], PS_TYPE_F32);
+        PS_IMAGE_SET_F32(tmpImage, ((float) r));
+        *(int *) (& (tmpImage->row0)) = baseRows[r];
+        *(int *) (& (tmpImage->col0)) = baseCols[r];
+        /*
+                psReadout *tmpReadout = psReadoutAlloc(baseColsReadout[r],
+                                                       baseRowsReadout[r],
+                                                       tmpImage);
+        */
+        psReadout *tmpReadout = psReadoutAlloc();
+        tmpReadout->image = tmpImage;
+        minOutRow = PS_MIN(minOutRow, (baseRowsReadout[r] + baseRows[r]));
+        minOutCol = PS_MIN(minOutCol, (baseColsReadout[r] + baseCols[r]));
+        maxOutRow = PS_MAX(maxOutRow, (baseRowsReadout[r] + baseRows[r] + numRows[r]));
+        maxOutCol = PS_MAX(maxOutCol, (baseColsReadout[r] + baseCols[r] + numCols[r]));
+
+        if (r == 0) {
+            list = psListAlloc(tmpReadout);
+        } else {
+            psListAdd(list, PS_LIST_HEAD, tmpReadout);
+        }
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL zero vector.\n");
+    rc = pmReadoutCombine(NULL, list, params, NULL, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (0.0 + (0.0 + VEC_SCALE * (NR - 1)))) / NR;
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+
+        if (rc->type.type != scale->type.type) {
+            printf("TEST ERROR: output readout->image has incorrect type.\n");
+            testStatus = false;
+        }
+        psFree(rc);
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroHalf, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type zero vector.  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroF64, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zeroBig, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL scale vector.\n");
+    rc = pmReadoutCombine(output, list, params, zero, NULL, true, 0.0, 0.0);
+
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + 1.0 * (NR - 1)))) / NR;
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+
+        if (rc->type.type != scale->type.type) {
+            printf("TEST ERROR: output readout->image has incorrect type.\n");
+            testStatus = false;
+        }
+        psFree(rc);
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleHalf, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type scale vector.  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleF64, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleBig, true, 0.0, 0.0);
+    if (rc != NULL) {
+        psF32 NR = (psF32) NUM_READOUTS;
+        psF32 expectedPixel = ((NR/2.0) * (VEC_ZERO + (VEC_ZERO + VEC_SCALE * (NR - 1)))) / NR;
+
+        if (false == VerifyTheOutput(rc, expectedPixel)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("TEST ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() insufficient size output image.  Should generate error, return NULL.\n");
+    output = psImageAlloc(1, 1, PS_TYPE_F32);
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    psFree(output);
+    output = NULL;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() row0/col0 too large.  Should generate error, return NULL.\n");
+    output = psImageAlloc(1, 1, PS_TYPE_F32);
+    *(psS32*)&output->row0 = 10000;
+    *(psS32*)&output->col0 = 10000;
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    psFree(output);
+    output = NULL;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL input list.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, NULL, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL params.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, NULL, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    psStatsOptions oldStatsOpts = params->stats->options |= PS_STAT_MIN;
+    printf("Calling pmReadoutCombine() with multiple stats->options.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats->options = oldStatsOpts;
+
+    printf("----------------------------------------------------------------------------\n");
+    psStats *oldStats = params->stats;
+    printf("Calling pmReadoutCombine() with NULL param->stats.  Should generate error, return NULL.\n");
+    params->stats = NULL;
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 0.0, 0.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats = oldStats;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("============================================================================\n");
+
+    psFree(params->stats);
+    psFree(params);
+    //    psFree(output);
+    //    psFree(rc);
+    psFree(zero);
+    psFree(zeroHalf);
+    psFree(zeroBig);
+    psFree(zeroF64);
+    psFree(scale);
+    psFree(scaleHalf);
+    psFree(scaleBig);
+    psFree(scaleF64);
+    psListElem *tmpInput = (psListElem *) list->head;
+    while (NULL != tmpInput) {
+        psReadout *tmpReadout = (psReadout *) tmpInput->data;
+        psFree(tmpReadout);
+        tmpInput = tmpInput->next;
+    }
+    psFree(list);
+
+    printFooter(stdout, "pmReadoutCombine", "Testing bad input parameter conditions", true);
+    return(!testStatus);
+}
Index: /branches/rel4/psModules/test/tst_pmSubtractBias.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmSubtractBias.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmSubtractBias.c	(revision 3057)
@@ -0,0 +1,1092 @@
+/** @file tst_pmSubtractBias.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.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-10 22:13:39 $
+ *
+ *  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);
+static int test04(void);
+static int testX(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias", 0, false},
+                              {test02, 000, "pmSubtractBias", 0, false},
+                              {test03, 000, "pmSubtractBias", 0, false},
+                              {test04, 000, "pmSubtractBias", 0, false},
+                              {testX,  000, "pmSubtractBias", 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
+/******************************************************************************
+doSubtractBiasFullFrame(): a sample psReadout as well as a bias image are
+created and the bias image is subtracted from the psReadout.
+ *****************************************************************************/
+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);
+    psReadout *myReadout = psReadoutAlloc();
+    psReadout *myBias = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    myBias->image = tmpImage2;
+
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractBiasFullFrame");
+    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("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myBias);
+    printFooter(stdout, "pmSubtractBias", "doSubtractBiasFullFrame", true);
+    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);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are then subtracted
+from the psReadout.
+ *****************************************************************************/
+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);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractFullOverscans");
+    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("TEST 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", "doSubtractFullOverscans", true);
+    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);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+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();
+    myReadout->image = 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("TEST 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);
+}
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsPoly(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();
+    myReadout->image = tmpImage1;
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+
+    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, myPoly, list, PM_OVERSCAN_COLUMNS, stat,
+                               0, PM_FIT_POLYNOMIAL, 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("TEST 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);
+    psFree(myPoly);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsSmall(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psImage *tmpImage2 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
+    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);
+        }
+    }
+    for (i=0;i<numRows/2;i++) {
+        for (j=0;j<numCols/2;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_POLYNOMIAL, 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("TEST 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);
+    /* These tests do not make sense until the SDRS is clarified.
+        testStatus |= doSubtractFullOverscanColumnsSmall(1, 1);
+        testStatus |= doSubtractFullOverscanColumnsSmall(1, NUM_ROWS);
+        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, 1);
+        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, NUM_ROWS);
+    */
+
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscans(): a sample psReadout as well as several overscan
+images of the same size are created.  The overscan images are collected
+pixel-by-pixel then subtracted row-wise from the psReadout.
+ *****************************************************************************/
+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();
+    myReadout->image = 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("TEST 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);
+}
+
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted row-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanRowsSmall(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psS32 OSnumRows = numRows-1;
+    if (OSnumRows == 0) {
+        OSnumRows = 1;
+    }
+    psS32 OSnumCols = numCols-1;
+    if (OSnumCols == 0) {
+        OSnumCols = 1;
+    }
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = 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);
+        }
+    }
+    for (i=0;i<OSnumRows;i++) {
+        for (j=0;j<OSnumCols;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_SPLINE, 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("TEST 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);
+    testStatus |= doSubtractFullOverscanRowsSmall(1, 1);
+    testStatus |= doSubtractFullOverscanRowsSmall(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+
+
+int doSubtractOverscansTestInputCases(int numCols, int numRows)
+{
+    int i;
+    int j;
+    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);
+    psImage *tmpImage2Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psImage *tmpImage3Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psImage *tmpImage4Short = psImageAlloc(numCols-1, numRows-1, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    psReadout *rc = NULL;
+    psList *list;
+    psList *listShort;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psImage *tmpImage5 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myBias = psReadoutAlloc();
+    myBias->image = tmpImage5;
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Testing input parameter error conditions");
+
+    psImage *tmpImage5ShortRows = psImageAlloc(numCols, numRows-1, PS_TYPE_F32);
+    psReadout *myBiasShortRows = psReadoutAlloc();
+    myBiasShortRows->image = tmpImage5ShortRows;
+    psImage *tmpImage5ShortCols = psImageAlloc(numCols-1, numRows, PS_TYPE_F32);
+    psReadout *myBiasShortCols = psReadoutAlloc();
+    myBiasShortCols->image = tmpImage5ShortCols;
+
+    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;
+            myBias->image->data.F32[i][j] = 1.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    for (i=0;i<numRows-1;i++) {
+        for (j=0;j<numCols-1;j++) {
+            tmpImage2Short->data.F32[i][j] = 3.0;
+            tmpImage3Short->data.F32[i][j] = 4.0;
+            tmpImage4Short->data.F32[i][j] = 5.0;
+        }
+    }
+    listShort = psListAlloc(tmpImage2Short);
+    psListAdd(listShort, PS_LIST_HEAD, tmpImage3Short);
+    psListAdd(listShort, PS_LIST_HEAD, tmpImage4Short);
+    for (i=0;i<numRows-1;i++) {
+        for (j=0;j<numCols;j++) {
+            myBiasShortRows->image->data.F32[i][j] = 1.0;
+        }
+    }
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols-1;j++) {
+            myBiasShortCols->image->data.F32[i][j] = 1.0;
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ALL.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_ALL, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ROWS.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_ROWS, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_COLUMNS.  Should generate error.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_COLUMNS, stat, 0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with non-NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_NONE, stat, 0, PM_FIT_NONE, myBias);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    /* XXX: This does not seem to be a requirement.
+        printf("------------------------------------------------------------------\n");
+        printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
+        rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat,
+                            0, PM_FIT_NONE, myBias);
+     
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 1.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+     
+                // Restore myReadout for next test.
+                myReadout->image->data.F32[i][j] = (float) (i + j);
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with PM_OVERSCAN_NONE and PM_FIT_POLYNOMIAL.  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat, 0, PM_FIT_POLYNOMIAL, myBias);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with PM_OVERSCAN_ALL and PM_FIT_SPLINE.  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, stat, 0, PM_FIT_SPLINE, myBias);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            psF32 expect = ((float) (i + j)) - 1.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+
+            // Restore myReadout for next test.
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with multiple stats->options.  Should generate Warning.\n");
+    stat->options|= PS_STAT_SAMPLE_MEDIAN;
+    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++) {
+            psF32 expect = ((float) (i + j)) - 12.0;
+            psF32 actual = rc->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+    stat->options = PS_STAT_SAMPLE_MEAN;
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_ROWS).  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_ROWS, stat,
+                        0, PM_FIT_NONE, NULL);
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_COLUMNS).  Should generate Warning.\n");
+    rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_COLUMNS, stat,
+                        0, PM_FIT_NONE, NULL);
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize bias image (short rows).  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBiasShortRows);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() undersize bias image (short columns).  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBiasShortCols);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with bogus PM_FIT.  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
+                               0, 54321, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    printf("------------------------------------------------------------------\n");
+    printf("Calling pmSubtractBias() with bogus overScanAxis.  Should generate Error.\n");
+    myReadout = pmSubtractBias(myReadout, NULL, list, 54321, stat,
+                               0, PM_FIT_NONE, NULL);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractBias() did not return input psReadout.\n");
+        testStatus = false;
+        psFree(rc);
+    }
+
+    /*
+        for (i=0;i<numRows;i++) {
+            for (j=0;j<numCols;j++) {
+                psF32 expect = ((float) (i + j)) - 12.0;
+                psF32 actual = rc->image->data.F32[i][j];
+                if (FLT_EPSILON < fabs(expect - actual)) {
+                    printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                    testStatus = 1;
+                }
+            }
+        }
+    */
+
+    printf("------------------------------------------------------------------\n");
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(tmpImage2Short);
+    psFree(tmpImage3Short);
+    psFree(tmpImage4Short);
+    psFree(myBias);
+    psFree(myBiasShortRows);
+    psFree(myBiasShortCols);
+    psFree(stat);
+    psFree(list);
+    psFree(listShort);
+
+    printFooter(stdout, "pmSubtractBias", "Testing input parameter error conditions", true);
+    return(testStatus);
+}
+
+int test04( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractOverscansTestInputCases(NUM_COLS, NUM_ROWS);
+    return(testStatus);
+}
+
+/******************************************************************************
+doSubtractFullOverscansSmall(): a sample psReadout as well as several overscan
+images of smaller size are created.  The overscan images are collected
+pixel-by-pixel then subtracted column-wise from the psReadout.
+ *****************************************************************************/
+int doSubtractFullOverscanColumnsGeneric(int imageNumCols,
+        int imageNumRows,
+        int overscanNumCols,
+        int overscanNumRows,
+        pmOverscanAxis overscanaxis,
+        pmFit fit,
+        psS32 nBin)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+
+    psImage *tmpImage1 = psImageAlloc(imageNumCols, imageNumRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(imageNumCols, imageNumRows, tmpImage1);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImage1;
+    for (i=0;i<imageNumRows;i++) {
+        for (j=0;j<imageNumCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    psSpline1D *mySpline = NULL;
+
+
+    /*
+        if (overscanNumRows <= 0) {
+            overscanNumRows = 1;
+        }
+        if (overscanNumCols <= 0) {
+            overscanNumCols = 1;
+        }
+    */
+    psImage *tmpImage2 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+    psList *list;
+    for (i=0;i<overscanNumRows;i++) {
+        for (j=0;j<overscanNumCols;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");
+
+    if (fit == PM_FIT_NONE) {
+        myReadout = pmSubtractBias(myReadout, NULL, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    } else if (fit == PM_FIT_POLYNOMIAL) {
+        myReadout = pmSubtractBias(myReadout, myPoly, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    } else if (fit == PM_FIT_SPLINE) {
+        myReadout = pmSubtractBias(myReadout, mySpline, list, overscanaxis, stat,
+                                   nBin, fit, NULL);
+    }
+
+    for (i=0;i<imageNumRows;i++) {
+        for (j=0;j<imageNumCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("TEST 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);
+    psFree(myPoly);
+    psFree(mySpline);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+
+int testX( void )
+{
+    int testStatus = 0;
+
+    // imageNumCols, imageNumRows, overscanNumCols, overscanNumRows,
+    // overscanaxis, fit, nBin
+
+    //
+    // Overscan images are same size, no fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_NONE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_NONE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_NONE, 1);
+
+    //
+    // Overscan images are same size, no fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_NONE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_NONE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_NONE, 2);
+    //
+    // Overscan images are too small, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+    //
+    // Overscan images are too small, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS-1, NUM_ROWS-1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+    //
+    // Overscan images are same size, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+    //
+    // Overscan images are same size, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
+                  NUM_COLS, NUM_ROWS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    return(testStatus);
+}
+
Index: /branches/rel4/psModules/test/tst_pmSubtractSky.c
===================================================================
--- /branches/rel4/psModules/test/tst_pmSubtractSky.c	(revision 3057)
+++ /branches/rel4/psModules/test/tst_pmSubtractSky.c	(revision 3057)
@@ -0,0 +1,360 @@
+/** @file tst_pmSubtractSky.c
+ *
+ *  @brief Contains the tests for pmSubtractSky.c:
+ *
+ * test00: This code will ...
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 19:58:18 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include "psTest.h"
+#include "pslib.h"
+#include "pmSubtractSky.h"
+#define NUM_ROWS 512
+#define NUM_COLS 512
+#define POLY_X_ORDER 3
+#define POLY_Y_ORDER 3
+#define ERROR_TOLERANCE 1.0
+#define OBJECT_INTENSITY 2000.0
+static int test00(void);
+static int test01(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractSky", 0, false},
+                              {test01, 000, "pmSubtractSky: warning, error messages", 0, false},
+                              {NULL}
+                          };
+
+float func(int i, int j)
+{
+    return((float) (i + j));
+}
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+/******************************************************************************
+ *****************************************************************************/
+int doSubtractSkySimple(int numCols, int numRows, int binFactor)
+{
+    int i;
+    int j;
+    int testStatus = 0;
+    psImage *tmpImageF32 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "doSubtractSkySimple");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+
+    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+                              binFactor, myStats, 10.0);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            if (ERROR_TOLERANCE < fabs(myReadout->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j, myReadout->image->data.F32[i][j]);
+                testStatus = 1;
+            }
+        }
+    }
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    printFooter(stdout, "pmSubtractSky", "doSubtractSkySimple", true);
+    return(testStatus);
+}
+
+/******************************************************************************
+ *****************************************************************************/
+int doSubtractSkyWithObjects(int numCols, int numRows, int binFactor)
+{
+    int i;
+    int j;
+    int testStatus = 0;
+    psImage *tmpImageF32 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    //    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+    psImage *trueImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psF32 errorTolerance = ERROR_TOLERANCE * ((psF32) binFactor);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "doSubtractSkyWithObjects");
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+    // We insert a few bright spots in the image.
+    myReadout->image->data.F32[NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[3*NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    myReadout->image->data.F32[3*NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    PS_IMAGE_SET_F32(trueImage, 0.0);
+    trueImage->data.F32[NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[3*NUM_ROWS/4][NUM_COLS/4]+= OBJECT_INTENSITY;
+    trueImage->data.F32[3*NUM_ROWS/4][3*NUM_COLS/4]+= OBJECT_INTENSITY;
+
+    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+                              binFactor, myStats, 2.0);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            if (errorTolerance < fabs(myReadout->image->data.F32[i][j] - trueImage->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j,
+                       myReadout->image->data.F32[i][j], trueImage->data.F32[i][j]);
+                testStatus = 1;
+            }
+        }
+    }
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    psFree(trueImage);
+    printFooter(stdout, "pmSubtractSky", "doSubtractSkyWithObjects", true);
+    return(testStatus);
+}
+
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    psTraceSetLevel(".", 0);
+
+    // Bin Factor == 1
+    printf("doSubtractSkySimple(1, 1, 1)\n");
+    testStatus |= doSubtractSkySimple(1, 1, 1);
+    printf("doSubtractSkySimple(NUM_COLS, 1, 1)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, 1, 1);
+
+    printf("doSubtractSkySimple(1, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkySimple(1, NUM_ROWS, 1);
+    printf("doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1);
+
+    // Bin Factor == 2
+    printf("doSubtractSkySimple(1, 1, 2)\n");
+    testStatus |= doSubtractSkySimple(1, 1, 2);
+    printf("doSubtractSkySimple(NUM_COLS, 1, 2)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, 1, 2);
+    printf("doSubtractSkySimple(1, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkySimple(1, NUM_ROWS, 2);
+    printf("doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2);
+
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 4)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 4);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128);
+    printf("doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256)\n");
+    testStatus |= doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256);
+
+    return(testStatus);
+}
+
+#define NUM_ROWS_SMALL 16
+#define NUM_COLS_SMALL 16
+int test01( void )
+{
+    int testStatus = 0;
+    psS32 i;
+    psS32 j;
+    psImage *tmpImageF32 = psImageAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, PS_TYPE_F32);
+    psImage *tmpImageF64 = psImageAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, PS_TYPE_F64);
+    //    psReadout *myReadout = psReadoutAlloc(NUM_COLS_SMALL, NUM_ROWS_SMALL, tmpImageF32);
+    psReadout *myReadout = psReadoutAlloc();
+    myReadout->image = tmpImageF32;
+    psReadout *rc = NULL;
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial2D *myPoly = psPolynomial2DAlloc(POLY_X_ORDER, POLY_Y_ORDER, PS_POLYNOMIAL_ORD);
+
+    printPositiveTestHeader(stdout, "pmSubtractSky", "Testing bad input parameter conditions.");
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            myReadout->image->data.F32[i][j] = func(i, j);
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL psReadout.  Should error.\n\n");
+    rc = pmSubtractSky(NULL, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL psReadout->image.  Should error.\n\n");
+    myReadout->image = NULL;
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImageF32;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PS_TYPE_F64 psReadout->image.  Should error.\n\n");
+    myReadout->image = tmpImageF64;
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != NULL) {
+        printf("TEST ERROR: pmSubtractSky() returned a non-NULL psReadout\n");
+        testStatus = false;
+    }
+    myReadout->image = tmpImageF32;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL fitSpec.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, NULL, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PM_FIT_NONE fit.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_NONE, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with PM_FIT_SPLINE fit.  Should return image, no ERROR, no WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_SPLINE, 1, myStats, 2.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with NULL myStats.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, NULL, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    psU64 oldOptions = myStats->options;
+    myStats->options = 0;
+    printf("Calling pmSubtractSky() with no myStats->options specified.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+    myStats->options = oldOptions;
+
+    printf("----------------------------------------------------------------\n");
+    oldOptions = myStats->options;
+    myStats->options = PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN;
+    printf("Calling pmSubtractSky() with multiple myStats->options specified.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+    myStats->options = oldOptions;
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with 0 binFactor.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 0, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with -1 binFactor.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, -1, myStats, 2.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with -1.0 clipSD.  Should fit entire image, generate WARNING.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL, 1, myStats, -1.0);
+    for (i=0;i<NUM_ROWS_SMALL;i++) {
+        for (j=0;j<NUM_COLS_SMALL;j++) {
+            if (ERROR_TOLERANCE < fabs(rc->image->data.F32[i][j])) {
+                printf("TEST ERROR: image[%d][%d] is %f, should be 0.0\n", i, j,
+                       rc->image->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+
+    printf("----------------------------------------------------------------\n");
+    printf("Calling pmSubtractSky() with bogus psFit.  Should generate Error.\n\n");
+    rc = pmSubtractSky(myReadout, (void *) myPoly, 54321, 1, myStats, -1.0);
+    if (rc != myReadout) {
+        printf("TEST ERROR: pmSubtractSky() returned something other than psReadout\n");
+        testStatus = false;
+    }
+
+
+    //    myReadout = pmSubtractSky(myReadout, (void *) myPoly, PM_FIT_POLYNOMIAL,
+    //                              1, myStats, 2.0);
+
+
+    printf("----------------------------------------------------------------\n");
+    psFree(myReadout);
+    psFree(myStats);
+    psFree(myPoly);
+    psFree(tmpImageF64);
+    printFooter(stdout, "pmSubtractSky", "Testing bad input parameter conditions.", true);
+    return(testStatus);
+}
Index: /branches/rel4/psModules/test/verified/tst_pmFlatField.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmFlatField.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmFlatField.stderr	(revision 3057)
@@ -0,0 +1,29 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: Test Point Driver{pmFlatField}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Null not allowed for flat readout.
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Null not allowed for input image.
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Null not allowed for flat image.
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Input image size exceeds that of flat image: (3, 3) vs (2, 2)
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Input image mask size exceeds that of flat image: (4, 4) vs (3, 3)
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Total offset >= flat image size: (50, 50) vs (3, 3)
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Complex types not allowed for input image. Type: 2064
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Complex types not allowed for flat image. Type: 2064
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Input and flat image types differ: (1032 vs 1028)
+<DATE><TIME>|<HOST>|E|pmFlatField (pmFlatField.c:<LINENO>)
+    Mask must be PS_TYPE_MASK type. Type: 1028
+
+---> TESTPOINT PASSED (Test Point Driver{pmFlatField} | tst_pmFlatField.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmFlatField.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmFlatField.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmFlatField.stdout	(revision 3057)
@@ -0,0 +1,236 @@
+/***************************** 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 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+
+---> 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 
+3.000000 -3.000000 0.000000 
+
+Flat image out:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+3.000000 0.000000 0.000000 
+
+Resulting mask:
+8 8 8 
+8 8 8 
+0 8 8 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+1.000000 3.000000 3.000000 
+
+
+---> 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/rel4/psModules/test/verified/tst_pmMaskBadPixels.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 3057)
@@ -0,0 +1,113 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on maskVal argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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                                                   *
+\**********************************************************************************/
+
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Null not allowed for mask image.
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Input image size exceeds that of mask image: (60, 60) vs (50, 50)
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Input image mask size exceeds that of mask image: (60, 60) vs (50, 50)
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Total offset >= mask image: (150, 150) vs (50, 50)
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Complex types not allowed for input image. Type: 2064
+
+---> 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|pmMaskBadPixels (pmMaskBadPixels.c:<LINENO>)
+    Mask must be PS_TYPE_MASK type. Type: 1032
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use non-mask type mask image} | tst_pmMaskBadPixels.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmMaskBadPixels.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 3057)
@@ -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
+
Index: /branches/rel4/psModules/test/verified/tst_pmNonLinear.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmNonLinear.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmNonLinear.stderr	(revision 3057)
@@ -0,0 +1,72 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityPolynomial}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityPolynomial} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityLookup}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityLookup} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityPolynomial(): error/warning conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (pmNonLinear.c:<LINENO>)
+    Unallowable operation: inputReadout is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (pmNonLinear.c:<LINENO>)
+    Unallowable operation: inputReadout->image is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityPolynomial (pmNonLinear.c:<LINENO>)
+    Unallowable operation: input1DPoly is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityPolynomial(): error/warning conditions} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: Test Point Driver{pmNonLinearityLookup(): error/warning conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (pmNonLinear.c:<LINENO>)
+    Unallowable operation: inputReadout is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (pmNonLinear.c:<LINENO>)
+    Unallowable operation: inputReadout->image is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (pmNonLinear.c:<LINENO>)
+    Unallowable operation: inFlux is NULL.
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (pmNonLinear.c:<LINENO>)
+    Unallowable operation: outFlux is NULL.
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (24, 25)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (24, 23)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (23, 24)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (25, 24)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (23, 25)
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): input vectors have different sizes (25, 23)
+<DATE><TIME>|<HOST>|E|pmNonLinearityLookup (pmNonLinear.c:<LINENO>)
+    pmNonLinearityLookup(): input vector less than 2 elements.  Returning inputReadout image.
+<DATE><TIME>|<HOST>|W|vectorBinDisectF32
+    vectorBinDisectF32(): ordinate -1.000000 is outside vector range (0.000000 - 23.000000).
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): 1 pixels outside table.
+<DATE><TIME>|<HOST>|W|vectorBinDisectF32
+    vectorBinDisectF32(): ordinate 100.000000 is outside vector range (0.000000 - 23.000000).
+<DATE><TIME>|<HOST>|W|pmNonLinearityLookup
+    WARNING: pmNonLinear.c: pmNonLinearityLookup(): 1 pixels outside table.
+
+---> TESTPOINT PASSED (Test Point Driver{pmNonLinearityLookup(): error/warning conditions} | tst_pmNonLinear.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmNonLinear.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmNonLinear.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmNonLinear.stdout	(revision 3057)
@@ -0,0 +1,115 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityPolynomialTest}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityPolynomialTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{doNonLinearityLookupTest}                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmNonLinear{doNonLinearityLookupTest} | tst_pmNonLinear.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmNonLinear.c                                          *
+*            TestPoint: pmNonLinear{Testing bad input parameter conditions.}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL input readout.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL input readout->image.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityPolynomial() with NULL polynomial.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL input psReadout.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL input psReadout->image.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL inFlux psVector.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with NULL outFlux psVector.  Should generate error, return NULL.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with size difference in inFlux/outFLux psVectors.  Should generate warning.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with inFlux psVector size 1.  Should generate error, return original psReadout.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with one pixels outside inFlux range.  Should generate warnings.
+------------------------------------------------------------
+Calling pmNonLinearityLookup() with image values not in vector.
+
+---> TESTPOINT PASSED (pmNonLinear{Testing bad input parameter conditions.} | tst_pmNonLinear.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stderr	(revision 3057)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: Test Point Driver{pmSubtractBias(): input parameter error conditions} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    zero vector has incorrect size (5).  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Unallowable operation: psVector zero has incorrect type.
+<DATE><TIME>|<HOST>|W|pmReadoutCombine
+    WARNING: the zero vector too many elements (11)
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    scale vector has incorrect size (5).  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Unallowable operation: psVector scale has incorrect type.
+<DATE><TIME>|<HOST>|W|pmReadoutCombine
+    WARNING: the scale vector has too many elements (20)
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Output image (1, 1) is too small to hold combined images.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Output image offset is larger then input image offset.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Unallowable operation: inputs is NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Unallowable operation: params is NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Multiple statistical options have been requested.  Returning NULL.
+<DATE><TIME>|<HOST>|E|pmReadoutCombine (pmReadoutCombine.c:<LINENO>)
+    Unallowable operation: params->stats is NULL.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias(): input parameter error conditions} | tst_pmReadoutCombine.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmReadoutCombine.stdout	(revision 3057)
@@ -0,0 +1,79 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (1, 1)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (1, 20)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (20, 1)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{simpleCombineNoOverlap}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tst_pmReadoutCombine(): (minOutRow, minOutCol) to (maxOutRow, maxOutCol) is (0, 0) (20, 20)
+
+---> TESTPOINT PASSED (pmReadoutCombine{simpleCombineNoOverlap} | tst_pmReadoutCombine.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmReadoutCombine.c                                     *
+*            TestPoint: pmReadoutCombine{Testing bad input parameter conditions}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL zero vector.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length zero vector (too small).  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect type zero vector.  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length zero vector (too big).  Should generate warning.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL scale vector.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length scale vector (too small).  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect type scale vector.  Should generate error.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with incorrect length scale vector (too big).  Should generate warning.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() insufficient size output image.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() row0/col0 too large.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL input list.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL params.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with multiple stats->options.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+Calling pmReadoutCombine() with NULL param->stats.  Should generate error, return NULL.
+----------------------------------------------------------------------------
+============================================================================
+
+---> TESTPOINT PASSED (pmReadoutCombine{Testing bad input parameter conditions} | tst_pmReadoutCombine.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stderr	(revision 3057)
@@ -0,0 +1,132 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    (overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE).  Returning in image
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE and overscans does not equal NULL.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals NONE, and fit does not equal NONE.  Proceeding to full fram subtraction.
+<DATE><TIME>|<HOST>|W|GenNewStatOptions
+    WARNING: pmSubtractBias.c: GenNewStatOptions(): Too many statistics options have been specified
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    Don't know how to scale the overscan vector.  Set fit to PM_FIT_SPLINE or PM_FIT_POLYNOMIAL.  Returning in image.
+<DATE><TIME>|<HOST>|E|psSubtractFrame (pmSubtractBias.c:<LINENO>)
+    bias image does not have enough rows.  Returning in image
+<DATE><TIME>|<HOST>|E|psSubtractFrame (pmSubtractBias.c:<LINENO>)
+    bias image does not have enough columns.  Returning in image
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    fit is unallowable (54321).  Returning in image.
+<DATE><TIME>|<HOST>|E|pmSubtractBias (pmSubtractBias.c:<LINENO>)
+    overScanAxis is unallowable (54321).  Returning in image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: Test Point Driver{pmSubtractBias}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 rows, input image has 8 rows
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overscan image has 7 columns, input image has 8 columns
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+<DATE><TIME>|<HOST>|W|pmSubtractBias
+    WARNING: pmSubtractBias.(): overScanAxis equals ALL, and fit does not equal NONE.  Proceeding with the rest of the module.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractBias} | tst_pmSubtractBias.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmSubtractBias.stdout	(revision 3057)
@@ -0,0 +1,432 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractBiasFullFrame}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractBiasFullFrame} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{doSubtractFullOverscans}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{doSubtractFullOverscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Row Overscans}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Row Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Testing input parameter error conditions}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ALL.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ROWS.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_COLUMNS.  Should generate error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with non-NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with PM_OVERSCAN_NONE and PM_FIT_POLYNOMIAL.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with PM_OVERSCAN_ALL and PM_FIT_SPLINE.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() with multiple stats->options.  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_ROWS).  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_COLUMNS).  Should generate Warning.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize bias image (short rows).  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() undersize bias image (short columns).  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with bogus PM_FIT.  Should generate Error.
+------------------------------------------------------------------
+Calling pmSubtractBias() with bogus overScanAxis.  Should generate Error.
+------------------------------------------------------------------
+
+---> TESTPOINT PASSED (pmSubtractBias{Testing input parameter error conditions} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractBias.c                                       *
+*            TestPoint: pmSubtractBias{Column Overscans}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractBias{Column Overscans} | tst_pmSubtractBias.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stderr
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stderr	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stderr	(revision 3057)
@@ -0,0 +1,62 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: Test Point Driver{pmSubtractSky}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|W|p_psVectorSampleStdev
+    WARNING: p_psVectorSampleStdev(): only one valid psVector elements (1).  Setting stats->sampleStdev = 0.0.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|p_psVectorSampleStdev
+    WARNING: p_psVectorSampleStdev(): only one valid psVector elements (1).  Setting stats->sampleStdev = 0.0.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in x-dimension.
+<DATE><TIME>|<HOST>|W|ImageFitPolynomial
+    WARNING: ImageFitPolynomial(): Reducing polynomial complexity in y-dimension.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractSky} | tst_pmSubtractSky.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: Test Point Driver{pmSubtractSky: warning, error messages}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|pmSubtractSky (pmSubtractSky.c:<LINENO>)
+    Unallowable operation: psReadout in or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSubtractSky (pmSubtractSky.c:<LINENO>)
+    Unallowable operation: psReadout in or its data is NULL.
+<DATE><TIME>|<HOST>|E|pmSubtractSky (pmSubtractSky.c:<LINENO>)
+    Unallowable operation: psImage in has incorrect type.
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): input parameter stats is NULL
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): no stats->options was requested
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: Multiple statistical options have been requested.
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): binFactor is 0
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): binFactor is -1
+<DATE><TIME>|<HOST>|W|pmSubtractSky
+    WARNING: pmSubtractSky(): clipSD is -1.000000
+<DATE><TIME>|<HOST>|E|pmSubtractSky (pmSubtractSky.c:<LINENO>)
+    psFit is unallowable (54321).  Returning in image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmSubtractSky: warning, error messages} | tst_pmSubtractSky.c)
+
Index: /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stdout
===================================================================
--- /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stdout	(revision 3057)
+++ /branches/rel4/psModules/test/verified/tst_pmSubtractSky.stdout	(revision 3057)
@@ -0,0 +1,219 @@
+doSubtractSkySimple(1, 1, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, 1, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, 1, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, 1, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(1, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkySimple(NUM_COLS, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkySimple}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkySimple} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 1)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 2)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 4)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 8)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 16)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 32)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 64)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 128)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+doSubtractSkyWithObjects(NUM_COLS, NUM_ROWS, 256)
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{doSubtractSkyWithObjects}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmSubtractSky{doSubtractSkyWithObjects} | tst_pmSubtractSky.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmSubtractSky.c                                        *
+*            TestPoint: pmSubtractSky{Testing bad input parameter conditions.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL psReadout.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL psReadout->image.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PS_TYPE_F64 psReadout->image.  Should error.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL fitSpec.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PM_FIT_NONE fit.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with PM_FIT_SPLINE fit.  Should return image, no ERROR, no WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with NULL myStats.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with no myStats->options specified.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with multiple myStats->options specified.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with 0 binFactor.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with -1 binFactor.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with -1.0 clipSD.  Should fit entire image, generate WARNING.
+
+----------------------------------------------------------------
+Calling pmSubtractSky() with bogus psFit.  Should generate Error.
+
+----------------------------------------------------------------
+
+---> TESTPOINT PASSED (pmSubtractSky{Testing bad input parameter conditions.} | tst_pmSubtractSky.c)
+
