Index: /branches/2.0/drmaa2_utils/INSTALL
===================================================================
--- /branches/2.0/drmaa2_utils/INSTALL	(revision 77)
+++ /branches/2.0/drmaa2_utils/INSTALL	(revision 77)
@@ -0,0 +1,237 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   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, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   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 you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' 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.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+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 can use 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 `..'.
+
+   With a non-GNU `make', it is safer 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' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   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' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   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 machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+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.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
Index: /branches/2.0/drmaa2_utils/COPYING
===================================================================
--- /branches/2.0/drmaa2_utils/COPYING	(revision 77)
+++ /branches/2.0/drmaa2_utils/COPYING	(revision 77)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /branches/2.0/drmaa2_utils/Makefile.am
===================================================================
--- /branches/2.0/drmaa2_utils/Makefile.am	(revision 77)
+++ /branches/2.0/drmaa2_utils/Makefile.am	(revision 77)
@@ -0,0 +1,28 @@
+# $Id: Makefile.am 13 2011-04-20 15:41:43Z mmamonski $
+#
+# FedStage DRMAA utilities library
+# Copyright (C) 2006-2008  FedStage Systems
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+
+ACLOCAL_AMFLAGS = -I m4
+EXTRA_DIST = \
+ autoclean.sh \
+ autogen.sh \
+ m4/bison_ylwrap.sh \
+ m4/missing-dev-prog.sh
+
+SUBDIRS = drmaa_utils tests
+
Index: /branches/2.0/drmaa2_utils/configure.ac
===================================================================
--- /branches/2.0/drmaa2_utils/configure.ac	(revision 77)
+++ /branches/2.0/drmaa2_utils/configure.ac	(revision 77)
@@ -0,0 +1,233 @@
+AC_INIT([PSNC DRMAA 2.0 utilities library], [2.0.1], [mamonski@man.poznan.pl], [drmaa2_utils])
+AC_PREREQ(2.59)
+AC_REVISION([$Id: configure.ac 13 2011-04-20 15:41:43Z mmamonski $])
+AC_COPYRIGHT([
+PSNC DRMAA utilities library
+Copyright (C) 2012  Poznan Supercomputing and Networking Center
+
+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 3 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, see <http://www.gnu.org/licenses/>.
+])
+
+DRMAA_UTILS_MAJOR=2
+DRMAA_UTILS_MINOR=0
+DRMAA_UTILS_MICRO=1
+DRMAA_UTILS_VERSION_INFO=2:1:0
+AC_SUBST([DRMAA_UTILS_MAJOR])
+AC_SUBST([DRMAA_UTILS_MINOR])
+AC_SUBST([DRMAA_UTILS_MICRO])
+AC_SUBST([DRMAA_UTILS_VERSION_INFO])
+
+AC_CONFIG_SRCDIR([drmaa_utils/xmalloc.c])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_AUX_DIR([scripts])
+
+AM_INIT_AUTOMAKE
+DEVELOPER_MODE="no"
+AM_CONDITIONAL([DEVELOPER_MODE], [test "x$DEVELOPER_MODE" = "xyes"])
+
+# command-line arguments:
+AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
+			[produce code suiteable for debugging and print logs at runtime]))
+AC_ARG_ENABLE(development, AC_HELP_STRING([--enable-development],
+			[enable development mode: make additional checks (suiteable for PSNC DRMAA utilities library developers)]))
+
+AC_ARG_WITH(drmaa-utils, AC_HELP_STRING([--with-drmaa-utils=...],
+		[used only to detect that drmaa utils is sub packaged]))
+AM_CONDITIONAL([DRMAA_UTILS_STANDALONE],
+		[test x$with_drmaa_utils = x])
+
+# programs:
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_LIBTOOL
+AC_PROG_MAKE_SET
+AC_PROG_LN_S
+
+AC_ARG_VAR([SED], [Location of the sed utility])
+AC_PATH_PROG(SED, [sed])
+AC_SUBST([SED])
+
+AC_ARG_VAR([TR], [Location of the tr utility])
+AC_PATH_PROG([TR], [tr])
+
+
+# code generation tools:
+AC_PROG_YACC
+AX_GPERF
+AC_CHECK_PROGS([RAGEL], [ragel], [sh m4/missing-dev-prog.sh ragel])
+
+# reStructuredText processing:
+AX_DOCUTILS
+# documentation generation:
+AC_CHECK_PROGS([DOT], [dot])
+if test x$DOT != x; then
+	HAVE_DOT=yes
+else
+	HAVE_DOT=no
+fi
+AC_SUBST([HAVE_DOT])
+
+# check compiler / set basic flags:
+if test x$ac_cv_prog_cc_stdc = xno; then
+	AC_MSG_ERROR([ANSI C compiler is required])
+fi
+
+if test x$GCC = xyes; then
+	CFLAGS="-pedantic -ansi ${CFLAGS}"
+fi
+AM_CONDITIONAL([GCC], [test x$GCC = xyes])
+
+AX_GCC_WARNINGS()
+
+AH_TEMPLATE([DEBUGGING], [Produce debugging code])
+if test x$enable_debug = xyes; then
+	AC_DEFINE(DEBUGGING,[1])
+	CFLAGS="${CFLAGS} -O0"
+else
+	CPPFLAGS="-DNDEBUG ${CPPFLAGS}"
+fi
+
+AH_TEMPLATE([DEVELOPMENT], [Development mode])
+if test x$enable_development = xyes; then
+	AC_DEFINE(DEVELOPMENT, [1])
+fi
+
+AH_BOTTOM([
+#ifndef __GNUC__
+#	define __attribute__ /* nothing */
+#endif
+])
+
+# system:
+CPPFLAGS="-D_REENTRANT -D_THREAD_SAFE ${CPPFLAGS}"
+
+AC_CANONICAL_HOST
+case "$host_os" in
+	*linux*)
+		CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE"
+		;;
+	*solaris*)
+		CPPFLAGS="${CPPFLAGS} -D_XOPEN_SOURCE=500 -D__EXTENSIONS__"
+		;;
+	*freebsd*)
+		;;
+	*darwin*)
+		CPPFLAGS="${CPPFLAGS} -D_XOPEN_SOURCE=400"
+		;;
+	*aix*)                                                                                                                                                                                                                                  
+		CPPFLAGS="${CPPFLAGS} -D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED=1 -D__linux__"  
+		;;
+	*)
+		CPPFLAGS="${CPPFLAGS} -D_XOPEN_SOURCE=500 -D__USE_BSD"
+		;;
+esac
+
+
+AC_C_BIGENDIAN_CROSS
+
+# project prerequisites:
+
+# libraries:
+ACX_PTHREAD([CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS"],
+		[AC_MSG_ERROR([POSIX threads library is required by DRMAA.])])
+
+# headers:
+AC_CHECK_HEADERS([execinfo.h fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h])
+AC_HEADER_STDBOOL
+AC_HEADER_TIME
+
+# types and structures:
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_MODE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+AC_STRUCT_TM
+AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
+
+# compiler characteristic
+AC_C_CONST
+AC_C_INLINE
+AC_C_VOLATILE
+
+# functions:
+AC_FUNC_ALLOCA
+AC_FUNC_STRERROR_R
+AC_FUNC_STRFTIME
+AC_CHECK_FUNCS([ \
+	asprintf \
+	fstat \
+	getcwd \
+	gettimeofday \
+	localtime_r \
+	memset \
+	strchr \
+	strdup \
+	strerror \
+	strlcpy \
+	strndup \
+	strstr \
+	vasprintf])
+AX_FUNC_GETTID
+AX_FUNC_VA_COPY
+AC_SEARCH_LIBS([backtrace], [execinfo])
+
+# system services:
+
+# turn on warning after all tests
+if test x$GCC = xyes; then
+	if test x$enable_development = xyes; then
+		CFLAGS="-Werror ${CFLAGS}"
+	fi
+	CFLAGS="-Wall -W -Wno-unused  $GCC_W_NO_FORMAT_ZERO_LENGTH  $GCC_W_NO_MISSING_FIELD_INITIALIZERS ${CFLAGS}"
+fi
+
+# put all usefull paths in config.h
+AH_TEMPLATE([DRMAA_DIR_PREFIX], [The installation prefix])
+AH_TEMPLATE([DRMAA_DIR_BIN], [Location of binary files])
+AH_TEMPLATE([DRMAA_DIR_SYSCONF], [Location of system configuration files])
+AH_TEMPLATE([DRMAA_DIR_LOCALSTATE], [Location of variable data files])
+AH_TEMPLATE([DRMAA_DIR_DATA], [Location of package data files])
+
+test "$prefix" = NONE && prefix="$ac_default_prefix"
+test "$exec_prefix" = NONE && exec_prefix='${prefix}'
+
+for i in bindir prefix localstatedir  sysconfdir datadir; do
+        name=`echo $i | $SED -e 's/dir$//' | $TR 'a-z' 'A-Z'`
+        x="\$$i"
+        eval y="$x"
+        while test "$x" != "$y"; do
+                x="$y"
+                eval y="$x"
+        done
+        AC_DEFINE_UNQUOTED([DRMAA_DIR_$name], ["$x"])
+done
+
+
+AC_CONFIG_FILES([
+	Makefile
+	drmaa_utils/Makefile
+  tests/Makefile
+	Doxyfile
+])
+AC_CONFIG_HEADERS([config.h])
+AC_OUTPUT
+
+echo
+echo "Run 'make' now."
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/drmaa2.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/drmaa2.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/drmaa2.h	(revision 77)
@@ -0,0 +1,431 @@
+#include <time.h>
+
+#ifndef DRMAA2_H
+#define DRMAA2_H
+
+typedef enum drmaa2_jstate {
+  DRMAA2_UNDETERMINED                =  0,
+  DRMAA2_QUEUED                      =  1,
+  DRMAA2_QUEUED_HELD                 =  2,
+  DRMAA2_RUNNING                     =  3,
+  DRMAA2_SUSPENDED                   =  4,
+  DRMAA2_REQUEUED                    =  5,
+  DRMAA2_REQUEUED_HELD               =  6,
+  DRMAA2_DONE                        =  7,
+  DRMAA2_FAILED                      =  8
+} drmaa2_jstate;
+
+typedef enum drmaa2_os {
+  DRMAA2_OTHER_OS                    =  0,
+  DRMAA2_AIX                         =  1,
+  DRMAA2_BSD                         =  2,
+  DRMAA2_LINUX                       =  3,
+  DRMAA2_HPUX                        =  4,
+  DRMAA2_IRIX                        =  5,
+  DRMAA2_MACOS                       =  6,
+  DRMAA2_SUNOS                       =  7,
+  DRMAA2_TRU64                       =  8,
+  DRMAA2_UNIXWARE                    =  9,
+  DRMAA2_WIN                         = 10,
+  DRMAA2_WINNT                       = 11
+} drmaa2_os;
+
+typedef enum drmaa2_cpu {
+  DRMAA2_OTHER_CPU                   =  0,
+  DRMAA2_ALPHA                       =  1,
+  DRMAA2_ARM                         =  2,
+  DRMAA2_ARM64                       =  3,
+  DRMAA2_CELL                        =  4,
+  DRMAA2_PARISC                      =  5,
+  DRMAA2_PARISC64                    =  6,
+  DRMAA2_X86                         =  7,
+  DRMAA2_X64                         =  8,
+  DRMAA2_IA64                        =  9,
+  DRMAA2_MIPS                        = 10,
+  DRMAA2_MIPS64                      = 11,
+  DRMAA2_PPC                         = 12,
+  DRMAA2_PPC64                       = 13,
+  DRMAA2_SPARC                       = 14,
+  DRMAA2_SPARC64                     = 15
+} drmaa2_cpu;
+
+typedef enum drmaa2_limit {
+  DRMAA2_CORE_FILE_SIZE              =  0,
+  DRMAA2_CPU_TIME                    =  1,
+  DRMAA2_DATA_SIZE                   =  2,
+  DRMAA2_FILE_SIZE                   =  3,
+  DRMAA2_OPEN_FILES                  =  4,
+  DRMAA2_STACK_SIZE                  =  5,
+  DRMAA2_VIRTUAL_MEMORY              =  6,
+  DRMAA2_WALLCLOCK_TIME              =  7
+} drmaa2_limit;
+
+typedef enum drmaa2_event {
+  DRMAA2_NEW_STATE                   =  0,
+  DRMAA2_MIGRATED                    =  1,
+  DRMAA2_ATTRIBUTE_CHANGE            =  2
+} drmaa2_event;
+
+typedef enum drmaa2_capability {
+  DRMAA2_ADVANCE_RESERVATION         =  0,
+  DRMAA2_RESERVE_SLOTS               =  1,
+  DRMAA2_CALLBACK                    =  2,
+  DRMAA2_BULK_JOBS_MAXPARALLEL       =  3,
+  DRMAA2_JT_EMAIL                    =  4,
+  DRMAA2_JT_STAGING                  =  5,
+  DRMAA2_JT_DEADLINE                 =  6,
+  DRMAA2_JT_MAXSLOTS                 =  7,
+  DRMAA2_JT_ACCOUNTINGID             =  8,
+  DRMAA2_RT_STARTNOW                 =  9,
+  DRMAA2_RT_DURATION                 = 10,
+  DRMAA2_RT_MACHINEOS                = 11,
+  DRMAA2_RT_MACHINEARCH              = 12
+} drmaa2_capability;
+
+typedef enum drmaa2_bool {
+  DRMAA2_FALSE                       =  0,
+  DRMAA2_TRUE                        =  1
+} drmaa2_bool;
+
+typedef enum drmaa2_error {
+  DRMAA2_SUCCESS                 =  0,
+  DRMAA2_DENIED_BY_DRMS          =  1,
+  DRMAA2_DRM_COMMUNICATION       =  2,
+  DRMAA2_TRY_LATER               =  3,
+  DRMAA2_SESSION_MANAGEMENT      =  4,
+  DRMAA2_TIMEOUT                 =  5,
+  DRMAA2_INTERNAL                =  6,
+  DRMAA2_INVALID_ARGUMENT        =  7,
+  DRMAA2_INVALID_SESSION         =  8,
+  DRMAA2_INVALID_STATE           =  9,
+  DRMAA2_OUT_OF_RESOURCE         = 10,
+  DRMAA2_UNSUPPORTED_ATTRIBUTE   = 11,
+  DRMAA2_UNSUPPORTED_OPERATION   = 12,
+  DRMAA2_IMPLEMENTATION_SPECIFIC = 13,
+  DRMAA2_LASTERROR               = 14
+} drmaa2_error;
+
+typedef char * drmaa2_string;
+void drmaa2_string_free(drmaa2_string *);
+
+drmaa2_error  drmaa2_lasterror(void);
+drmaa2_string drmaa2_lasterror_text(void);
+
+struct drmaa2_list_s;        /*forward*/
+typedef struct drmaa2_list_s * drmaa2_list;
+typedef struct drmaa2_list_s * drmaa2_string_list;
+typedef struct drmaa2_list_s * drmaa2_j_list;
+typedef struct drmaa2_list_s * drmaa2_queueinfo_list;
+typedef struct drmaa2_list_s * drmaa2_machineinfo_list;
+typedef struct drmaa2_list_s * drmaa2_slotinfo_list;
+typedef struct drmaa2_list_s * drmaa2_r_list;
+
+typedef enum drmaa2_listtype {
+  DRMAA2_STRINGLIST,        
+  DRMAA2_JOBLIST,
+  DRMAA2_QUEUEINFOLIST,
+  DRMAA2_MACHINEINFOLIST,
+  DRMAA2_SLOTINFOLIST,
+  DRMAA2_RESERVATIONLIST
+} drmaa2_listtype;
+
+typedef void (*drmaa2_list_entryfree)(void **value);
+drmaa2_list  drmaa2_list_create (const drmaa2_listtype t, const drmaa2_list_entryfree callback);
+void         drmaa2_list_free   (      drmaa2_list * l); 
+const void * drmaa2_list_get    (const drmaa2_list l, long pos);
+drmaa2_error drmaa2_list_add    (      drmaa2_list l, const void * value);
+drmaa2_error drmaa2_list_del    (      drmaa2_list l, long pos);
+long         drmaa2_list_size   (const drmaa2_list l);
+
+struct drmaa2_dict_s;        /*forward*/
+typedef struct drmaa2_dict_s * drmaa2_dict;
+
+typedef void (*drmaa2_dict_entryfree)(char **key, char **val);
+drmaa2_dict         drmaa2_dict_create (const drmaa2_dict_entryfree callback);
+void                drmaa2_dict_free   (      drmaa2_dict * d); 
+drmaa2_string_list  drmaa2_dict_list   (const drmaa2_dict d);            
+drmaa2_bool         drmaa2_dict_has    (const drmaa2_dict d, const char * key);
+const char *        drmaa2_dict_get    (const drmaa2_dict d, const char * key);
+drmaa2_error        drmaa2_dict_del    (      drmaa2_dict d, const char * key);
+drmaa2_error        drmaa2_dict_set    (      drmaa2_dict d, const char * key, const char * val);
+
+#define  DRMAA2_ZERO_TIME       ((time_t)  0)
+#define  DRMAA2_INFINITE_TIME   ((time_t) -1)
+#define  DRMAA2_NOW             ((time_t) -2)
+#define  DRMAA2_HOME_DIR        "$DRMAA2_HOME_DIR$"
+#define  DRMAA2_WORKING_DIR     "$DRMAA2_WORKING_DIR$"
+#define  DRMAA2_INDEX           "$DRMAA2_INDEX$"
+
+#define  DRMAA2_UNSET_BOOL      DRMAA2_FALSE
+#define  DRMAA2_UNSET_STRING    NULL   
+#define  DRMAA2_UNSET_NUM       -1     
+#define  DRMAA2_UNSET_ENUM      -1
+#define  DRMAA2_UNSET_LIST      NULL
+#define  DRMAA2_UNSET_DICT      NULL
+#define  DRMAA2_UNSET_TIME      ((time_t) -3)
+#define  DRMAA2_UNSET_CALLBACK  NULL    
+#define  DRMAA2_UNSET_JINFO     NULL
+
+
+typedef struct {
+  drmaa2_string      jobId;
+  int                exitStatus;        
+  drmaa2_string      terminatingSignal;
+  drmaa2_string      annotation;
+  drmaa2_jstate      jobState;
+  drmaa2_string      jobSubState;
+  drmaa2_string_list allocatedMachines;
+  drmaa2_string      submissionMachine;
+  drmaa2_string      jobOwner;
+  long long          slots;
+  drmaa2_string      queueName;
+  time_t             wallclockTime;
+  long long          cpuTime;
+  time_t             submissionTime;
+  time_t             dispatchTime;
+  time_t             finishTime;
+} drmaa2_jinfo_s;
+typedef drmaa2_jinfo_s * drmaa2_jinfo;
+
+drmaa2_jinfo drmaa2_jinfo_create (void);
+void         drmaa2_jinfo_free   (drmaa2_jinfo * ji);
+
+typedef struct {
+  drmaa2_string        machineName; 
+  long long            slots;
+} drmaa2_slotinfo_s;
+typedef drmaa2_slotinfo_s * drmaa2_slotinfo;
+
+void drmaa2_slotinfo_free   (drmaa2_slotinfo * si);
+
+typedef struct {
+  drmaa2_string        reservationId;
+  drmaa2_string        reservationName;
+  time_t               reservedStartTime;
+  time_t               reservedEndTime;
+  drmaa2_string_list   usersACL;
+  long long            reservedSlots;
+  drmaa2_slotinfo_list reservedMachines;
+} drmaa2_rinfo_s;
+typedef drmaa2_rinfo_s * drmaa2_rinfo;
+
+void drmaa2_rinfo_free   (drmaa2_rinfo * ri);
+
+typedef struct {
+  drmaa2_string      remoteCommand;          
+  drmaa2_string_list args;          
+  drmaa2_bool        submitAsHold;
+  drmaa2_bool        rerunnable;
+  drmaa2_dict        jobEnvironment;        
+  drmaa2_string      workingDirectory;        
+  drmaa2_string      jobCategory;            
+  drmaa2_string_list email;            
+  drmaa2_bool        emailOnStarted;
+  drmaa2_bool        emailOnTerminated;
+  drmaa2_string      jobName;              
+  drmaa2_string      inputPath;            
+  drmaa2_string      outputPath;            
+  drmaa2_string      errorPath;            
+  drmaa2_bool        joinFiles;
+  drmaa2_string      reservationId;          
+  drmaa2_string      queueName;            
+  long long          minSlots;              
+  long long          maxSlots;              
+  long long          priority;              
+  drmaa2_string_list candidateMachines;  
+  long long          minPhysMemory;            
+  drmaa2_os          machineOS;        
+  drmaa2_cpu         machineArch;      
+  time_t             startTime;          
+  time_t             deadlineTime;        
+  drmaa2_dict        stageInFiles;        
+  drmaa2_dict        stageOutFiles;        
+  drmaa2_dict        resourceLimits;      
+  drmaa2_string      accountingId;          
+} drmaa2_jtemplate_s;
+typedef drmaa2_jtemplate_s * drmaa2_jtemplate;
+
+drmaa2_jtemplate drmaa2_jtemplate_create   (void);
+void             drmaa2_jtemplate_free     (drmaa2_jtemplate * jt);
+
+typedef struct {
+  drmaa2_string      reservationName;          
+  time_t             startTime;          
+  time_t             endTime;          
+  time_t             duration;          
+  long long          minSlots;              
+  long long          maxSlots;
+  drmaa2_string      jobCategory;
+  drmaa2_string_list usersACL;            
+  drmaa2_string_list candidateMachines;  
+  long long          minPhysMemory;            
+  drmaa2_os          machineOS;        
+  drmaa2_cpu         machineArch;      
+} drmaa2_rtemplate_s;
+typedef drmaa2_rtemplate_s * drmaa2_rtemplate;
+
+drmaa2_rtemplate     drmaa2_rtemplate_create (void);
+void                 drmaa2_rtemplate_free   (drmaa2_rtemplate * rt);
+
+typedef struct {
+  drmaa2_event   event;
+  drmaa2_string  jobId;
+  drmaa2_string  sessionName;
+  drmaa2_jstate  jobState;
+} drmaa2_notification_s;
+typedef drmaa2_notification_s * drmaa2_notification;
+
+void drmaa2_notification_free   (drmaa2_notification * n);
+
+typedef struct {
+  drmaa2_string                name;
+} drmaa2_queueinfo_s;
+typedef drmaa2_queueinfo_s * drmaa2_queueinfo;
+
+void drmaa2_queueinfo_free   (drmaa2_queueinfo * qi);
+
+typedef struct {
+  drmaa2_string                major; 
+  drmaa2_string                minor;
+} drmaa2_version_s;
+typedef drmaa2_version_s * drmaa2_version;
+
+void drmaa2_version_free   (drmaa2_version * v);
+
+typedef struct {
+  drmaa2_string   name;  
+  drmaa2_bool     available;    
+  long long       sockets;      
+  long long       coresPerSocket;
+  long long       threadsPerCore;  
+  float           load;  
+  long long       physMemory;
+  long long       virtMemory;    
+  drmaa2_os       machineOS;  
+  drmaa2_version  machineOSVersion;
+  drmaa2_cpu      machineArch;
+} drmaa2_machineinfo_s;
+typedef drmaa2_machineinfo_s * drmaa2_machineinfo;
+
+void drmaa2_machineinfo_free   (drmaa2_machineinfo * mi);
+
+drmaa2_string_list drmaa2_jtemplate_impl_spec     (void);
+drmaa2_string_list drmaa2_jinfo_impl_spec         (void);
+drmaa2_string_list drmaa2_rtemplate_impl_spec     (void);
+drmaa2_string_list drmaa2_rinfo_impl_spec         (void);
+drmaa2_string_list drmaa2_queueinfo_impl_spec     (void);
+drmaa2_string_list drmaa2_machineinfo_impl_spec   (void);
+drmaa2_string_list drmaa2_notification_impl_spec  (void);
+
+drmaa2_string drmaa2_get_instance_value (const void * instance, const char * name);
+drmaa2_string drmaa2_describe_attribute (const void * instance, const char * name);
+drmaa2_error  drmaa2_set_instance_value (      void * instance, const char * name, const char * value);
+
+typedef void (*drmaa2_callback)(drmaa2_notification * notification);
+
+struct drmaa2_jsession_s; /*forward*/
+struct drmaa2_rsession_s; /*forward*/
+struct drmaa2_msession_s; /*forward*/
+struct drmaa2_j_s;	      /*forward*/
+struct drmaa2_jarray_s;   /*forward*/
+struct drmaa2_r_s;        /*forward*/
+
+typedef struct drmaa2_jsession_s * drmaa2_jsession;
+typedef struct drmaa2_rsession_s * drmaa2_rsession;
+typedef struct drmaa2_msession_s * drmaa2_msession;
+typedef struct drmaa2_j_s        * drmaa2_j;
+typedef struct drmaa2_jarray_s   * drmaa2_jarray;
+typedef struct drmaa2_r_s        * drmaa2_r;
+
+void drmaa2_jsession_free(drmaa2_jsession * js);
+void drmaa2_rsession_free(drmaa2_rsession * rs);
+void drmaa2_msession_free(drmaa2_msession * ms);
+void drmaa2_j_free       (drmaa2_j * j);
+void drmaa2_jarray_free  (drmaa2_jarray * ja);
+void drmaa2_r_free       (drmaa2_r * r);
+
+drmaa2_string  drmaa2_rsession_get_contact          (const drmaa2_rsession rs);
+drmaa2_string  drmaa2_rsession_get_session_name     (const drmaa2_rsession rs); 
+drmaa2_r       drmaa2_rsession_get_reservation      (const drmaa2_rsession rs, const drmaa2_string reservationId);
+drmaa2_r       drmaa2_rsession_request_reservation  (const drmaa2_rsession rs, const drmaa2_rtemplate rt);
+drmaa2_r_list  drmaa2_rsession_get_reservations     (const drmaa2_rsession rs);
+
+drmaa2_string     drmaa2_r_get_id                   (const drmaa2_r r);
+drmaa2_string     drmaa2_r_get_session_name         (const drmaa2_r r);
+drmaa2_rtemplate  drmaa2_r_get_reservation_template (const drmaa2_r r);
+drmaa2_rinfo      drmaa2_r_get_info                 (const drmaa2_r r);
+drmaa2_error      drmaa2_r_terminate                (drmaa2_r r);
+
+drmaa2_string    drmaa2_jarray_get_id            (const drmaa2_jarray ja);
+drmaa2_j_list    drmaa2_jarray_get_jobs          (const drmaa2_jarray ja); 
+drmaa2_string    drmaa2_jarray_get_session_name  (const drmaa2_jarray ja);
+drmaa2_jtemplate drmaa2_jarray_get_job_template  (const drmaa2_jarray ja); 
+drmaa2_error     drmaa2_jarray_suspend           (drmaa2_jarray ja); 
+drmaa2_error     drmaa2_jarray_resume            (drmaa2_jarray ja); 
+drmaa2_error     drmaa2_jarray_hold              (drmaa2_jarray ja); 
+drmaa2_error     drmaa2_jarray_release           (drmaa2_jarray ja); 
+drmaa2_error     drmaa2_jarray_terminate         (drmaa2_jarray ja); 
+
+drmaa2_string       drmaa2_jsession_get_contact         (const drmaa2_jsession js); 
+drmaa2_string       drmaa2_jsession_get_session_name    (const drmaa2_jsession js);
+drmaa2_string_list  drmaa2_jsession_get_job_categories  (const drmaa2_jsession js); 
+drmaa2_j_list       drmaa2_jsession_get_jobs            (const drmaa2_jsession js, 
+                                                         const drmaa2_jinfo filter);
+drmaa2_jarray       drmaa2_jsession_get_job_array       (const drmaa2_jsession js, 
+                                                         const drmaa2_string jobarrayId);
+drmaa2_j            drmaa2_jsession_run_job             (const drmaa2_jsession js, 
+                                                         const drmaa2_jtemplate jt);
+drmaa2_jarray       drmaa2_jsession_run_bulk_jobs       (const drmaa2_jsession js, 
+                                                         const drmaa2_jtemplate jt, 
+                                                         unsigned long begin_index, 
+                                                         unsigned long end_index, 
+                                                         unsigned long step, 
+                                                         unsigned long max_parallel);
+drmaa2_j            drmaa2_jsession_wait_any_started    (const drmaa2_jsession js, 
+                                                         const drmaa2_j_list l, 
+                                                         const time_t timeout);
+drmaa2_j            drmaa2_jsession_wait_any_terminated (const drmaa2_jsession js, 
+                                                         const drmaa2_j_list l, 
+                                                         const time_t timeout);
+
+drmaa2_string      drmaa2_j_get_id            (const drmaa2_j j);
+drmaa2_string      drmaa2_j_get_session_name  (const drmaa2_j j);
+drmaa2_jtemplate   drmaa2_j_get_jt            (const drmaa2_j j);
+drmaa2_error       drmaa2_j_suspend           (drmaa2_j j); 
+drmaa2_error       drmaa2_j_resume            (drmaa2_j j); 
+drmaa2_error       drmaa2_j_hold              (drmaa2_j j); 
+drmaa2_error       drmaa2_j_release           (drmaa2_j j); 
+drmaa2_error       drmaa2_j_terminate         (drmaa2_j j); 
+drmaa2_jstate      drmaa2_j_get_state         (const drmaa2_j j, drmaa2_string * substate); 
+drmaa2_jinfo       drmaa2_j_get_info          (const drmaa2_j j);
+drmaa2_error       drmaa2_j_wait_started      (const drmaa2_j j, const time_t timeout); 
+drmaa2_error       drmaa2_j_wait_terminated   (const drmaa2_j j, const time_t timeout); 
+
+drmaa2_r_list            drmaa2_msession_get_all_reservations  (const drmaa2_msession ms);
+drmaa2_j_list            drmaa2_msession_get_all_jobs          (const drmaa2_msession ms, 
+                                                                const drmaa2_jinfo filter);
+drmaa2_queueinfo_list    drmaa2_msession_get_all_queues        (const drmaa2_msession ms, 
+                                                                const drmaa2_string_list names);
+drmaa2_machineinfo_list  drmaa2_msession_get_all_machines      (const drmaa2_msession ms, 
+                                                                const drmaa2_string_list names);
+
+drmaa2_string       drmaa2_get_drms_name                (void);
+drmaa2_version      drmaa2_get_drms_version             (void);
+drmaa2_string       drmaa2_get_drmaa_name               (void);
+drmaa2_version      drmaa2_get_drmaa_version            (void);
+drmaa2_bool         drmaa2_supports                     (const drmaa2_capability c);
+drmaa2_jsession     drmaa2_create_jsession              (const char * session_name, const char * contact);
+drmaa2_rsession     drmaa2_create_rsession              (const char * session_name, const char * contact);
+drmaa2_jsession     drmaa2_open_jsession                (const char * session_name);
+drmaa2_rsession     drmaa2_open_rsession                (const char * session_name);
+drmaa2_msession     drmaa2_open_msession                (const char * session_name);
+drmaa2_error        drmaa2_close_jsession               (drmaa2_jsession js);
+drmaa2_error        drmaa2_close_rsession               (drmaa2_rsession rs);
+drmaa2_error        drmaa2_close_msession               (drmaa2_msession ms);
+drmaa2_error        drmaa2_destroy_jsession             (const char * session_name);
+drmaa2_error        drmaa2_destroy_rsession             (const char * session_name);
+drmaa2_string_list  drmaa2_get_jsession_names           (void);
+drmaa2_string_list  drmaa2_get_rsession_names           (void);
+drmaa2_error        drmaa2_register_event_notification  (const drmaa2_callback callback);
+
+#endif
Index: /branches/2.0/drmaa2_utils/drmaa_utils/job.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/job.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/job.h	(revision 77)
@@ -0,0 +1,246 @@
+/* $Id: job.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file job.h
+ * Job managing functions.
+ */
+
+#ifndef __DRMAA_UTILS__JOB_H
+#define __DRMAA_UTILS__JOB_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <sys/time.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/thread.h>
+
+/**
+ * Create new job structure.
+ * @return Sole reference to newly created job.
+ */
+fsd_job_t *
+fsd_job_new( char *job_id );
+
+/** Job state flags. */
+typedef enum {
+	/**
+	 * Job is in queued state (either active or hold in queue).
+	 */
+	FSD_JOB_QUEUED             = 1<<0,
+	/** Job is hold in queue. */
+	FSD_JOB_HOLD               = 1<<1,
+	/** Job is running (suspended or not). */
+	FSD_JOB_RUNNING            = 1<<2,
+	/**
+	 * Set when job was suspended within session by
+	 * drmaa_control(DRMAA_CONTROL_SUSPEND).
+	 */
+	FSD_JOB_SUSPENDED          = 1<<3,
+	/**
+	 * Whether we know that job terminated and its status
+	 * is waiting to rip.
+	 */
+	FSD_JOB_TERMINATED         = 1<<4,
+	/**
+	 * It is known that job was aborted by user.
+	 */
+	FSD_JOB_ABORTED            = 1<<5,
+
+	/**
+	 * Job was submitted in current session.
+	 * It is set for all jobs which are or was
+	 * in fsd_drmaa_session_t#jobs set.
+	 */
+	FSD_JOB_CURRENT_SESSION    = 1<<6,
+
+	/**
+	 * Job is removed from session (but references to job still
+	 * exist).  No such job shall exist in session's submited
+	 * jobs set.
+	 */
+	FSD_JOB_DISPOSED           = 1<<7,
+
+	FSD_JOB_MISSING            = 1<<8,
+
+	FSD_JOB_QUEUED_MASK      = FSD_JOB_QUEUED | FSD_JOB_HOLD,
+	FSD_JOB_RUNNING_MASK     = FSD_JOB_RUNNING | FSD_JOB_SUSPENDED,
+	FSD_JOB_TERMINATED_MASK  = FSD_JOB_TERMINATED | FSD_JOB_ABORTED,
+	FSD_JOB_STATE_MASK       = FSD_JOB_HOLD | FSD_JOB_RUNNING
+		| FSD_JOB_SUSPENDED | FSD_JOB_TERMINATED
+} fsd_job_flag_t;
+
+
+/** Submitted job data. */
+struct fsd_job_s {
+	/** Release reference to job. */
+	void (*release)( fsd_job_t *self );
+
+	/** Destroy job data. */
+	void (*destroy)( fsd_job_t *self );
+
+	/** Implements drmaa_control(). */
+	void (*control)( fsd_job_t *self, int action );
+
+	/** Fetch job state from DRM. */
+	void (*update_status)( fsd_job_t *self );
+
+	/** Return job termination status and resource usage for drmaa_wait(). */
+	void (*get_termination_status)( fsd_job_t *self,
+			int *status, fsd_iter_t **rusage_out );
+
+	/**
+	 * Called whenever job is detected to be missing from DRM queue
+	 * while stil being within DRMAA session.
+	 */
+	void (*on_missing)( fsd_job_t *self );
+
+	/**
+	 * Points to next job in list.
+	 * Used by #fsd_job_set_t.
+	 */
+	fsd_job_t *next;
+
+	/** Number of references. */
+	int ref_cnt;
+
+	/** Job identifier (as null terminated string). */
+	char *job_id;
+
+	/** DRMAA session which job was submitted in. */
+	fsd_drmaa_session_t *session;
+
+	/**
+	 * Time of last update of job status and rusage information
+	 * (when status, exit_status, cpu_usage, mem_usage and flags
+	 * fields was updated according to DRM).
+	 */
+	time_t last_update_time;
+
+	/** Job state flags.  @see job_flag_t */
+	unsigned flags;
+
+	/**
+	 * State of job (as returned by drmaa_job_ps())
+	 * from last retrieval from DRM.
+	 */
+	int state;
+
+	/** Exit status of job as from <tt>wait(2)</tt>. */
+	int exit_status;
+	/** Time of job submission (local). */
+	time_t submit_time;
+	/** Time when job started execution (taken from DRM). */
+	time_t start_time;
+	/** Time when job ended execution (taken from DRM). */
+	time_t end_time;
+	/** CPU time usage in seconds. */
+	long cpu_usage;
+	/** Resident memory usage in bytes. */
+	long mem_usage;
+	/** Virtual memory usage in bytes. */
+	long vmem_usage;
+	/** Total run time in seconds. */
+	long walltime;
+	/** List of space separated execution host names. */
+	char *execution_hosts;
+	/** Batch queue name */
+	char *queue;
+	/** Account string */
+	char *project;
+
+	/** Mutex for accessing fsd_job_s structure (beside #next pointer). */
+	fsd_mutex_t  mutex;
+	/** Job status changed condition. */
+	fsd_cond_t   status_cond;
+	/** Able to destroy condition variable (ref_cnt==1). */
+	fsd_cond_t   destroy_cond;
+};
+
+
+
+/** Create empty set of jobs. */
+fsd_job_set_t *
+fsd_job_set_new(void);
+
+struct fsd_job_set_s {
+	/** Destroy set of jobs (including contained job handles). */
+	void (*
+	destroy)( fsd_job_set_t *self );
+
+	/** Adds job to set. */
+	void (*
+	add)( fsd_job_set_t *self, fsd_job_t *job );
+
+	/** Remove job from set. */
+	void (*
+	remove)( fsd_job_set_t *self, fsd_job_t *job );
+
+	/**
+	 * Finds job with given job_id.
+	 * @param job_set Set of jobs to search in.
+	 * @param job_id Job identifier.
+	 * @return If successful job handle is returned
+	 * and caller have exclusive access right to it.
+	 * It should be released by #release().
+	 * \c NULL is returned when job was not found.
+	 */
+	fsd_job_t* (*
+	get)( fsd_job_set_t *self, const char *job_id );
+
+	/** Whether the set is empty. */
+	bool (*
+	empty)( fsd_job_set_t *self );
+
+	/**
+	 * Find any job in set which was terminated (either successfully or not).
+	 * It is usefull for drmaa_wait( DRMAA_JOB_IDS_ANY ) implementation.
+	 * @param job_set Set of jobs to search in.
+	 * @return New reference to terminated job
+	 *   or \c NULL if no such job is present in set.
+	 * @see fsd_job_find
+	 */
+	fsd_job_t* (*
+	find_terminated)( fsd_job_set_t *self );
+
+	/**
+	 * Return idenetifiers of all jobs in set.
+	 * @param job_set Set of jobs.
+	 * @return Vector of job idenetifiers
+	 *   when done free it with fsd_free_vector.
+	 */
+	char** (*
+	get_all_job_ids)( fsd_job_set_t *self );
+
+	void (*
+	signal_all)( fsd_job_set_t *self );
+
+	fsd_job_t    **tab;
+	size_t         tab_size;
+	uint32_t       tab_mask;
+	/** Number of jobs in set. */
+	unsigned       n_jobs;
+	/** Mutex for job set data (e.g. for adding/removing job from set). */
+	fsd_mutex_t    mutex;
+};
+
+#endif /* __DRMAA_UTILS__JOB_H */
Index: /branches/2.0/drmaa2_utils/drmaa_utils/util.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/util.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/util.h	(revision 77)
@@ -0,0 +1,164 @@
+/* $Id: util.h 30 2011-11-18 14:37:04Z mmamonski $ */
+/*
+ *  FedStage DRMAA utilities library
+ *  Copyright (C) 2006-2008  FedStage Systems
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file util.h
+ * Various functions.
+ */
+
+#ifndef __DRMAA_UTILS__UTIL_H
+#define __DRMAA_UTILS__UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <sys/time.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/compat.h>
+
+char *fsd_explode( const char *const *vector, char glue, int n );
+void fsd_free_vector( char **vector );
+char **fsd_copy_vector( const char *const * vector );
+char *fsd_replace( char *input, const char *placeholder, const char *value );
+
+char *fsd_strdup( const char *s );
+char *fsd_strndup( const char *s, size_t n );
+
+int fsd_atoi( const char *s );
+
+void
+fsd_str_append(
+		bool *truncated,
+		char **p, char *end,
+		const char *fmt, ...
+		)
+		__attribute__(( format( printf, 4, 5 ) ));
+
+size_t
+fsd_snprintf(
+		bool *truncated,
+		char *str, size_t size,
+		const char *fmt, ...
+		)
+		__attribute__(( format( printf, 4, 5 ) ));
+
+size_t
+fsd_vsnprintf(
+		bool *truncated,
+		char *str, size_t size,
+		const char *fmt, va_list args
+		);
+
+/**
+ * Behaves like asprintf function from standard C library
+ * except any errors are marked in error context structure.
+ *
+ * It substitutes `%m` format string as in glibc
+ * (with `strerror(errno)`).
+ */
+char *fsd_asprintf( const char *fmt, ... )
+		__attribute__(( format( __printf__, 1, 2 ) ));
+
+/**
+ * Behaves like vasprintf function from standard C library
+ * except any errors are marked in error context structure.
+ */
+char *fsd_vasprintf( const char *fmt, va_list args );
+
+/**
+ * Implements GNU version of strerror_r function - thread-safe
+ * function returning message describing error code.
+ *
+ * From Linux Programmer's Manual:
+ *
+ * <code> char *strerror_r(int errnum, char *buf, size_t buflen); </code>
+ *
+ * The GNU-specific strerror_r() returns a pointer to a string containing
+ * the error message.  This may be either a pointer to a string that the
+ * function stores in buf, or a pointer to some (immutable) static string
+ * (in which case buf is unused).  If the function stores a string in
+ * buf, then at most buflen bytes are stored (the string may be truncated
+ * if buflen is too small) and the string always includes a terminating
+ * null byte.
+ */
+const char *
+fsd_strerror_r( int errnum, char *buffer, size_t buffer_size );
+
+char *
+fsd_astrerror( int errnum, bool *malloced );
+
+/** Retrievs current system timestamp. */
+void fsd_get_time( struct timespec *ts );
+
+/** Add delta to timestamp. */
+void fsd_ts_add( struct timespec *a, const struct timespec *b );
+
+/**
+ * Compares two timestamps.
+ * @return Negative integer when a < b (a represents earlier timestamp),
+ *   positive integer when a > b or 0 when timestamps are equal.
+ */
+int fsd_ts_cmp( const struct timespec *a, const struct timespec *b );
+
+/**
+ * Reads file contents.
+ * @param filename  Path to the file.
+ * @param must_exist  Controls behaviour when file not exist
+ *   (or is not readable).  If set to \c true DRMAA_ERRNO_INTERNAL_ERROR
+ *   is raised on such occasion.  If set to \c false only
+ *   \a content is set to \c NULL and no error is raised.
+ * @param content  Filled with pointer to buffer with file contents
+ *   or \c NULL when error is encoureged.  Caller is responsible
+ *   for free()'ing it.
+ * @param length  Filled with length of \a content buffer.
+ */
+void
+fsd_read_file(
+		const char *filename, bool must_exist,
+		char **content, size_t *length
+		);
+
+/**
+ * Gets path to current working directory.
+ * @return  Path to process's current working directory
+ *   in malloc'ed '\0' terminated buffer
+ *   or \c NULL in case of error.
+ */
+char *
+fsd_getcwd(void);
+
+/**
+ * Returns signal name.
+ * @param signum  Valid signal number.
+ */
+const char *
+fsd_strsignal( int signum );
+
+/**
+ * Gets next line from the file
+ * @return  The next line of the file (dynamically allocated)
+ *   or \c NULL on EOF.
+ */
+char * fsd_readline(FILE *f);
+
+#endif /* __DRMAA_UTILS__UTIL_H */
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf.c	(revision 77)
@@ -0,0 +1,579 @@
+/* $Id: conf.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/conf_impl.h>
+#include <drmaa_utils/conf_tab.h>
+#include <drmaa_utils/logging.h>
+#include <drmaa_utils/util.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: conf.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+fsd_conf_dict_t *
+fsd_conf_read(
+	        fsd_conf_dict_t  * volatile configuration,
+		const char *filename, bool must_exist,
+		const char *content, size_t content_len
+		)
+{
+	fsd_conf_dict_t *volatile result = NULL;
+	fsd_conf_parser_t *parser = NULL;
+	fsd_conf_lexer_t *lexer = NULL;
+	char *file_content = NULL;
+	size_t file_content_len = 0;
+
+	fsd_log_enter((
+		"(filename=%s, must_exist=%s, content=%s)",
+		filename, must_exist ? "true" : "false", content
+		));
+
+	TRY
+	 {
+		fsd_malloc( parser, fsd_conf_parser_t );
+		fsd_malloc( lexer, fsd_conf_lexer_t );
+
+		parser->lexer = lexer;
+		parser->result = NULL;
+		parser->n_errors = 0;
+		parser->errors = NULL;
+
+		lexer->parser = parser;
+		lexer->filename = filename;
+		lexer->buffer = NULL;
+		lexer->buflen = 0;
+		lexer->pos = NULL;
+		lexer->lineno = 0;
+		lexer->cline = NULL;
+
+		if( filename )
+			TRY
+			 {
+				fsd_read_file(
+						filename, must_exist,
+						&file_content, &file_content_len
+						);
+			 }
+			EXCEPT_DEFAULT
+			 {
+				const fsd_exc_t *e = fsd_exc_get();
+				if( must_exist )
+					fsd_exc_raise_fmt( e->code(e), "%s: %s", filename, e->message(e) );
+				else
+				 {
+					fsd_log_warning(( "%s: %s", filename, e->message(e) ));
+				 }
+			 }
+			END_TRY
+
+		if( file_content )
+		 {
+			lexer->buffer = (const uchar*)file_content;
+			lexer->buflen = file_content_len;
+			fsd_log_trace(( "content from file" ));
+		 }
+		else if( content )
+		 {
+			lexer->buffer = (const uchar*)content;
+			lexer->buflen = content_len;
+			fsd_log_trace(( "content from memory" ));
+		 }
+
+		if( lexer->buffer )
+		 {
+			lexer->pos = lexer->cline = lexer->buffer;
+			lexer->lineno = 1;
+
+			fsd_conf_parse( parser, lexer );
+			result = parser->result;
+		 }
+
+		if( parser->n_errors > 0 )
+		 {
+			fsd_exc_raise(
+					fsd_exc_new(
+							FSD_ERRNO_INTERNAL_ERROR,
+							fsd_explode( (const char*const*)parser->errors, '\n',
+								parser->n_errors ),
+							true
+							)
+					);
+		 }
+	 }
+	ELSE
+	 {
+		configuration = fsd_conf_dict_merge( configuration, result );
+		result = NULL;
+	 }
+	FINALLY
+	 {
+		if( parser )
+		 {
+			if( parser->errors )
+			 {
+				int i;
+				for( i=0;  i < parser->n_errors;  i++ )
+					fsd_free( parser->errors[i] );
+				fsd_free( parser->errors );
+			 }
+			fsd_free( parser );
+		 }
+		fsd_free( lexer );
+		fsd_free( file_content );
+		fsd_conf_dict_destroy( result );
+	 }
+	END_TRY
+
+	fsd_log_return(( "" ));
+	return configuration;
+}
+
+
+
+int
+fsd_conf_lex(
+		union YYSTYPE *lvalp, struct YYLTYPE *locp,
+		fsd_conf_lexer_t *lexer
+		)
+{
+	const uchar *c = lexer->pos;
+	const uchar *end = lexer->buffer + lexer->buflen;
+	const char *error = NULL;
+	int result;
+
+	while( c<end )
+		switch( *c )
+		 {
+			case '#':  /* a comment */
+				while( c<end && *c != '\n' )
+					c++;
+			case '\n':  /* no break */
+				lexer->lineno++;
+				lexer->cline = c+1;
+			case ' ':  case '\t':  case '\r':  /* no break */
+				c++;
+				break;
+			default:
+				goto token_begin;
+		 }
+
+token_begin:
+	locp->first_line = lexer->lineno;
+	locp->first_column = c - lexer->cline + 1;
+
+	if( c == end )
+		result = 0;
+	else
+		switch( *c )
+		 {
+			case ':':  case ',':  case '{':  case '}':
+				result = *c++;
+				break;
+
+			case '0':  case '1':  case '2':  case '3':  case '4':
+			case '5':  case '6':  case '7':  case '8':  case '9':
+			 {
+				int v = 0;
+				while( c < end  &&  '0' <= *c  &&  *c <= '9' )
+				 {
+					v *= 10;
+					v += *c - '0';
+					c++;
+				 }
+				lvalp->integer = v;
+				result = INTEGER;
+				break;
+			 }
+
+			case '"':  case '\'':
+			 {
+				uchar delimiter;
+				const uchar *begin;
+				delimiter = *c++;
+				begin = c;
+                                
+				while( c < end  &&  *c != delimiter )
+					c++;
+				if( c == end )
+				 {
+					error = "expected string delimiter but EOF found";
+					result = LEXER_ERROR;
+				 }
+				else
+				 {
+					lvalp->string = fsd_strndup( (const char*)begin, c-begin );
+					result = STRING;
+					c++;
+				 }
+				break;
+			 }
+
+			default:
+			 {
+				const uchar *begin = c;
+				while( c<end  &&  !isspace(*c) )
+					switch( *c )
+					 {
+						case ':':  case ',':  case '{':  case '}':
+							goto end_of_string;
+						default:
+							c++;
+							break;
+					 }
+			end_of_string:
+				lvalp->string = fsd_strndup( (const char*)begin, c-begin );
+				result = STRING;
+				break;
+			 }
+		 }
+
+	locp->last_line = lexer->lineno;
+	locp->last_column = c - lexer->cline;
+	if( locp->last_column < locp->first_column )
+		locp->last_column = locp->first_column;
+	lexer->pos = c;
+
+	if( error )
+		fsd_conf_error( locp, lexer->parser, lexer, error );
+
+	return result;
+}
+
+
+
+void
+fsd_conf_error(
+		struct YYLTYPE *locp,
+		fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer,
+		const char *fmt, ...
+		)
+{
+	char *volatile message = NULL;
+	va_list args;
+
+	TRY
+	 {
+		va_start( args, fmt );
+		message = fsd_vasprintf( fmt, args );
+		va_end( args );
+
+		fsd_realloc( parser->errors, parser->n_errors+1, char* );
+		parser->errors[ parser->n_errors ] = fsd_asprintf(
+				"%s:%d:%d: %s",
+				parser->lexer->filename, locp->first_line, locp->first_column,
+				message );
+		fsd_log_error(("Parser error: %s:%d:%d: %s", parser->lexer->filename, locp->first_line, locp->first_column, message ));
+		parser->n_errors ++;
+	 }
+	FINALLY
+	 { fsd_free( message ); }
+	END_TRY
+}
+
+
+
+fsd_conf_option_t *
+fsd_conf_option_create( fsd_conf_type_t type, void *value )
+{
+	fsd_conf_option_t *o = NULL;
+
+	fsd_malloc( o, fsd_conf_option_t );
+	o->type = type;
+	switch( type )
+	 {
+		case FSD_CONF_INTEGER:
+			o->val.integer = *(int*)value;
+			break;
+		case FSD_CONF_STRING:
+			o->val.string = (char*)value;
+			break;
+		case FSD_CONF_DICT:
+			o->val.dict = (fsd_conf_dict_t*)value;
+			break;
+		default:
+			fsd_assert(false);
+			break;
+	 }
+	return o;
+}
+
+
+void
+fsd_conf_option_destroy( fsd_conf_option_t *option )
+{
+	if( option == NULL )
+		return;
+	switch( option->type )
+	 {
+		case FSD_CONF_INTEGER:
+			break;
+		case FSD_CONF_STRING:
+			fsd_free( option->val.string );
+			break;
+		case FSD_CONF_DICT:
+			fsd_conf_dict_destroy( option->val.dict );
+			break;
+		default:
+			fsd_assert( false );
+	 }
+	fsd_free( option );
+}
+
+
+fsd_conf_option_t *
+fsd_conf_option_merge( fsd_conf_option_t *lhs, fsd_conf_option_t *rhs )
+{
+	if( lhs->type == rhs->type  &&  rhs->type == FSD_CONF_DICT )
+	 {
+		lhs->val.dict = fsd_conf_dict_merge( lhs->val.dict, rhs->val.dict );
+		fsd_free( rhs );
+		return lhs;
+	 }
+	else
+	 {
+		fsd_conf_option_destroy( lhs );
+		return rhs;
+	 }
+}
+
+
+void
+fsd_conf_option_dump( fsd_conf_option_t *option )
+{
+	if( option == NULL )
+	 {
+		printf( "(null)" );
+		return;
+	 }
+	switch( option->type )
+	 {
+		case FSD_CONF_STRING:
+			printf( "\"%s\"", option->val.string );
+			break;
+		case FSD_CONF_INTEGER:
+			printf( "%d", option->val.integer );
+			break;
+		case FSD_CONF_DICT:
+			fsd_conf_dict_dump( option->val.dict );
+			break;
+	 }
+}
+
+
+
+struct fsd_conf_dict_s {
+	fsd_conf_dict_t *next;
+	char *key;
+	fsd_conf_option_t *value;
+};
+
+
+fsd_conf_dict_t *
+fsd_conf_dict_create(void)
+{
+	fsd_conf_dict_t *dict = NULL;
+	fsd_malloc( dict, fsd_conf_dict_t );
+	dict->next = NULL;
+	dict->key = NULL;
+	dict->value = NULL;
+	return dict;
+}
+
+
+void
+fsd_conf_dict_destroy( fsd_conf_dict_t *dict )
+{
+	fsd_conf_dict_t *i;
+	for( i = dict;  i != NULL;  )
+	 {
+		fsd_conf_dict_t *c = i;
+		i = i->next;
+		fsd_free( c->key );
+		fsd_conf_option_destroy( c->value );
+		fsd_free( c );
+	 }
+}
+
+
+fsd_conf_option_t *
+fsd_conf_dict_get(
+		fsd_conf_dict_t *dict, const char *key )
+{
+	fsd_conf_dict_t *i;
+	if( dict == NULL  ||  key == NULL )
+		return NULL;
+	for( i = dict->next;  i != NULL;  i = i->next )
+	 {
+		if( !strcmp( i->key, key ) )
+			return i->value;
+	 }
+	return NULL;
+}
+
+
+void
+fsd_conf_dict_set(
+		fsd_conf_dict_t *dict, const char *key, fsd_conf_option_t *value
+		)
+{
+	fsd_conf_dict_t *i;
+	for( i = dict->next;  i != NULL;  i = i->next )
+	 {
+		if( !strcmp( i->key, key ) )
+			break;
+	 }
+
+	if( i != NULL )
+	 {
+		fsd_conf_option_destroy( i->value );
+		i->value = value;
+	 }
+	else
+	 {
+		fsd_conf_dict_t* volatile n = NULL;
+		TRY
+		 {
+			fsd_malloc( n, fsd_conf_dict_t );
+			n->key = fsd_strdup( key );
+			n->value = value;
+		 }
+		EXCEPT_DEFAULT
+		 {
+			fsd_free( n );
+			fsd_exc_reraise();
+		 }
+		ELSE
+		 {
+			n->next = dict->next;
+			dict->next = n;
+		 }
+		END_TRY
+	 }
+}
+
+
+fsd_conf_dict_t *
+fsd_conf_dict_merge( fsd_conf_dict_t *lhs, fsd_conf_dict_t *rhs )
+{
+	fsd_conf_dict_t *i, *j;
+
+	if( lhs == NULL )
+		return rhs;
+
+	if( rhs == NULL )
+		return lhs;
+
+	for( j = rhs->next;  j != NULL;  )
+	 {
+		fsd_conf_dict_t *r = j;
+		j = j->next;
+
+		for( i = lhs->next;  i != NULL;  i = i->next )
+			if( !strcmp( i->key, r->key ) )
+				break;
+
+		if( i != NULL )
+		 {
+			i->value = fsd_conf_option_merge( i->value, r->value );
+			fsd_free( r->key );
+			fsd_free( r );
+		 }
+		else
+		 {
+			r->next = lhs->next;
+			lhs->next = r;
+		 }
+	 }
+
+	fsd_free( rhs );
+	return lhs;
+}
+
+
+void
+fsd_conf_dict_dump( fsd_conf_dict_t *dict )
+{
+	fsd_conf_dict_t *i;
+
+	if( dict == NULL )
+	 {
+		printf( "(null)" );
+		return;
+	 }
+	printf( "{" );
+	for( i=dict->next;  i;  i = i->next )
+	 {
+		if( i != dict->next )
+			printf( "," );
+		printf( " %s=", i->key );
+		fsd_conf_option_dump( i->value );
+	 }
+	printf( " }" );
+}
+
+
+fsd_conf_option_t *
+fsd_conf_option_create_noraise( fsd_conf_type_t type, void *value )
+{
+	fsd_conf_option_t *volatile result = NULL;
+	TRY{ result = fsd_conf_option_create( type, value ); }
+	EXCEPT_DEFAULT{}
+	END_TRY
+	return result;
+}
+
+fsd_conf_dict_t *
+fsd_conf_dict_create_noraise(void)
+{
+	fsd_conf_dict_t *volatile result = NULL;
+	TRY{ result = fsd_conf_dict_create(); }
+	EXCEPT_DEFAULT{}
+	END_TRY
+	return result;
+}
+
+int
+fsd_conf_dict_set_noraise(
+		fsd_conf_dict_t *dict, const char *key, fsd_conf_option_t *value )
+{
+	volatile int rc = FSD_ERRNO_SUCCESS;
+	TRY{ fsd_conf_dict_set( dict, key, value ); }
+	EXCEPT_DEFAULT
+	 {
+		const fsd_exc_t *e = fsd_exc_get();
+		rc = e->code(e);
+	 }
+	END_TRY
+	return rc;
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/logging.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/logging.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/logging.c	(revision 77)
@@ -0,0 +1,296 @@
+/* $Id: logging.c 23 2011-10-12 18:50:48Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_EXECINFO_H
+#	include <execinfo.h>
+#endif
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/logging.h>
+#include <drmaa_utils/lookup3.h>
+#include <drmaa_utils/thread.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: logging.c 23 2011-10-12 18:50:48Z mmamonski $";
+#endif
+
+
+static int fsd_logging_output = 2;
+
+fsd_verbose_level_t fsd_verbose_level =
+#ifdef DEBUGGING
+	FSD_LOG_TRACE
+#else
+	FSD_LOG_FATAL
+#endif
+;
+
+static struct timeval fsd_logging_start = {0, 0};
+
+static void fsd_log_check_verbosity( void );
+
+void
+fsd_set_verbosity_level( fsd_verbose_level_t level )
+{
+	fsd_verbose_level = level;
+}
+
+void
+fsd_set_logging_fd( int fd )
+{
+	fsd_logging_output = fd;
+}
+
+
+void
+fsd_color( char *output, size_t len, int n )
+{
+	uint32_t k = n;
+	k = hashword( &k, 1, 0 );
+	k %= 12;
+	snprintf( output, len, "\033[0;%d;%dm", k>=6, 31+k%6 );
+}
+
+
+char
+fsd_log_level_char( int level )
+{
+	switch( level )
+	 {
+		case FSD_LOG_TRACE:    return 't';
+		case FSD_LOG_DEBUG:    return 'd';
+		case FSD_LOG_INFO:     return 'I';
+		case FSD_LOG_WARNING:  return 'W';
+		case FSD_LOG_ERROR:    return 'E';
+		case FSD_LOG_FATAL:    return 'F';
+		default:               return '?';
+	 }
+}
+
+
+void
+_fsd_log( int level, const char *file, const char *function,
+		int kind, char *message )
+{
+	const bool color = false;
+	char colorbeg[16];
+	const char *colorend;
+	int tid;
+	long int seconds, microseconds;
+	const char *prefix;
+	const char *p;
+
+	if( level < (int)fsd_verbose_level )
+		return;
+
+	if( message == NULL )
+		return;
+
+	tid = fsd_thread_id();
+	if( color )
+	 {
+		fsd_color( colorbeg, sizeof(colorbeg), tid );
+		colorend = "\033[0m";
+	 }
+	else
+	 {
+		colorbeg[0] = '\0';
+		colorend = "";
+	 }
+
+	 {
+		struct timeval tv;
+		gettimeofday( &tv, NULL );
+		seconds = tv.tv_sec;
+		microseconds = tv.tv_usec;
+	 }
+	if( fsd_logging_start.tv_sec == 0 )
+	 {
+		time_t t;
+		struct tm utc;
+		char rep[32];
+		fsd_log_check_verbosity();
+
+		fsd_logging_start.tv_sec = seconds;
+		fsd_logging_start.tv_usec = microseconds;
+		t = seconds;
+		gmtime_r( &t, &utc );
+		strftime( rep, sizeof(rep), "%Y-%m-%d %H:%M:%S", &utc );
+		fsd_log_info(( "logging started at: %s.%02ld Z", rep, microseconds/10000 ));
+		/* recheck */
+		if( level < (int)fsd_verbose_level )
+			return;
+
+	 }
+	if( microseconds < fsd_logging_start.tv_usec )
+	 {
+		seconds --;
+		microseconds += 1000000;
+	 }
+	seconds -= fsd_logging_start.tv_sec;
+	microseconds -= fsd_logging_start.tv_usec;
+
+	switch( kind )
+	 {
+		case _FSD_LOG_ENTER:   prefix = "->";  break;
+		case _FSD_LOG_RETURN:  prefix = "<-";  break;
+		default:
+			prefix = " *";
+			function = "";
+			break;
+	 }
+
+	p = message;
+	do {
+		if( *p == '\n' )
+		 {
+			prefix = " |";
+			function = "";
+			p++;
+		 }
+		else
+		 {
+			const char *end;
+			char *line = NULL;
+			int rc;
+			end = strchr( p, '\n' );
+			if( end == NULL )
+				end = p + strlen(p);
+			rc = asprintf( &line, "%c #%s%04x%s [%6ld.%02ld] %s %s%.*s\n",
+					fsd_log_level_char(level), colorbeg, tid, colorend,
+					seconds, microseconds/10000, prefix, function, (int)(end-p), p
+					);
+			if( rc != -1 )
+				write( fsd_logging_output, line, strlen(line) );
+			else
+				return;
+			free( line );
+			p = end;
+		 }
+	} while( *p != '\0' );
+
+	free( message );
+}
+
+
+void 
+fsd_log_check_verbosity( void )
+{
+	const char *log_level_str = getenv("DRMAA_LOG_LEVEL");
+
+	if (log_level_str == NULL) 
+	 {
+		return;
+	 } 
+	else if (strcmp(log_level_str, "TRACE") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_TRACE;
+	 } 
+	else if (strcmp(log_level_str, "DEBUG") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_DEBUG;
+	 } 
+	else if (strcmp(log_level_str, "INFO") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_INFO;
+	 } 
+	else if (strcmp(log_level_str, "WARNING") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_WARNING;
+	 } 
+	else if (strcmp(log_level_str, "ERROR") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_ERROR;
+	 } 
+	else if (strcmp(log_level_str, "FATAL") == 0) 
+	 {
+		fsd_verbose_level = FSD_LOG_FATAL;
+	 } 
+	else 
+	 {
+		fsd_log_error(( "Illegal value of DRMAA_LOG_LEVEL=%s. Using default logging verbosity.", log_level_str));
+	 } 
+}
+
+
+void
+fsd_log_fmt( int level, const char *fmt, ... )
+{
+	va_list args;
+	va_start( args, fmt );
+	fsd_log_fmtv( level, fmt, args );
+	va_end( args );
+}
+
+
+void
+fsd_log_fmtv( int level, const char *fmt, va_list args )
+{
+	_fsd_log( level, NULL, NULL, _FSD_LOG_MSG, fsd_vasprintf(fmt, args) );
+}
+
+
+#if defined(__GNUC__) && defined(HAVE_EXECINFO_H)
+#define MAX_STACKTRACE 128
+void
+fsd_log_stacktrace( int skip, int limit )
+{
+	void **ptr_buf = NULL;
+	const char **symbols = NULL;
+	int i, n;
+
+	if( limit == 0 )
+		limit = 128;
+	skip++; /* without fsd_log_stacktrace() frame */
+	n = skip + limit;
+
+	ptr_buf = (void**)calloc( n, sizeof(void*) );
+	if( ptr_buf == NULL )
+		return;
+	n = backtrace( ptr_buf, n );
+	symbols = (const char**)backtrace_symbols( ptr_buf, n );
+	if( symbols != NULL )
+	 {
+		fsd_log_debug(( "Stacktrace (most recent call last):" ));
+		for( i = n-skip;  i >= 0;  i-- )
+			fsd_log_debug(( "\n  %s", symbols[i] ));
+		free( symbols );
+	 }
+}
+#else
+void fsd_log_stacktrace( int skip, int limit ) {}
+#endif
+
+
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/session.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/session.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/session.h	(revision 77)
@@ -0,0 +1,331 @@
+/* $Id: session.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file session.h
+ * DRMAA session.
+ */
+
+#ifndef __DRMAA_UTILS__SESSION_H
+#define __DRMAA_UTILS__SESSION_H
+
+#include <sys/time.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/thread.h>
+
+/** Creates new DRMAA session. */
+fsd_drmaa_session_t *
+fsd_drmaa_session_new( const char *contact );
+
+/**
+ * Get current (global) DRMAA session
+ * and increase it's reference count.
+ */
+fsd_drmaa_session_t *
+fsd_drmaa_session_get(void);
+
+/**
+ * An action to be taken when job is missing from queue.
+ */
+typedef enum {
+	/**
+	 * Always raise #FSD_ERRNO_INTERNAL_ERROR (one per job)
+	 * in drmaa_wait() or drmaa_synchronize()
+	 * when job disappearance is spotted.
+	 */
+	FSD_REVEAL_MISSING_JOBS,
+	/**
+	 * Treat missing jobs as terminated with status
+	 * depending on last known state and action (drmaa_control()).
+	 */
+	FSD_IGNORE_MISSING_JOBS,
+	/**
+	 * Treat missing jobs as terminated
+	 * but only before they enter into running state.
+	 */
+	FSD_IGNORE_QUEUED_MISSING_JOBS
+} fsd_missing_jobs_behaviour_t;
+
+
+/** DRMAA session data. */
+struct fsd_drmaa_session_s {
+	/** Release one reference to DRMAA session. */
+	void (*
+	release)( fsd_drmaa_session_t *self );
+
+	/**
+	 * Destroy session after ensuring no other references to it are held.
+	 *
+	 * May block until reference count decreases to 1.
+	 * May return before actual session destruction if another thread
+	 * have already taken responsibility for freeing session.
+	 */
+	void (*
+	destroy)(
+			fsd_drmaa_session_t *self );
+
+	/**
+	 * Destroy session without waiting for releasing references.
+	 */
+	void (*
+	destroy_nowait)( fsd_drmaa_session_t *self );
+
+
+	/** Implements drmaa_run_job(). */
+	char* (*
+	run_job)(
+			fsd_drmaa_session_t *self,
+			const fsd_template_t *jt
+			);
+
+	/** Implements drmaa_run_bulk_jobs(). */
+	fsd_iter_t* (*
+	run_bulk)(
+			fsd_drmaa_session_t *self,
+			const fsd_template_t *jt,
+			int start, int end, int incr
+			);
+
+	/** Implements drmaa_control(). */
+	void (*
+	control_job)(
+			fsd_drmaa_session_t *self,
+			const char *job_id, int action
+			);
+
+	/** Implements drmaa_job_ps(). */
+	void (*
+	job_ps)(
+			fsd_drmaa_session_t *self,
+			const char *job_id, int *remote_ps
+			);
+
+	/** Implements drmaa_synchronize(). */
+	void (*
+	synchronize)(
+			fsd_drmaa_session_t *self,
+			const char **input_job_ids, const struct timespec *timeout,
+			bool dispose
+			);
+
+	/**
+	 * Implements drmaa_wait() call.
+	 * @param self     DRMAA session.
+	 * @param job_id   Job identifer to wait for or #DRMAA_JOB_IDS_SESSION_ANY
+	 * @param timeout  Timeout after which call shall raise
+	 *   #FSD_DRMAA_ERRNO_EXIT_TIMEOUT if job not terminated or \c NULL.
+	 * @param status   Terminated job status (output only).
+	 * @param rusage   Job resource usage (output only).
+	 * @see drmaa_wait()
+	 * @see #wait_for_single_job  #wait_for_any_job
+	 */
+	char* (*
+	wait)(
+			fsd_drmaa_session_t *self,
+			const char *job_id, const struct timespec *timeout,
+			int *status, fsd_iter_t **rusage
+			);
+
+	/**
+	 * Construct new job object.
+	 * @return Reference to newly created job.
+	 */
+	fsd_job_t* (*
+	new_job)( fsd_drmaa_session_t *self, const char *job_id );
+
+	char* (*
+	run_impl)(
+			fsd_drmaa_session_t *self,
+			const fsd_template_t *jt, int bulk_incr
+			);
+
+	/**
+	 * Wait until given job terminates (either successfuly or not).
+	 * @param self     DRMAA session.
+	 * @param job_id   Identifier of job to wait for.
+	 * @param timeout  If not \c NULL and job does not terminate
+	 *   in given amount of time function returns and
+	 *   #FSD_DRMAA_ERRNO_EXIT_TIMEOUT is raised.
+	 * @param status   If not \c NULL job status code is stored here.
+	 * @param rusage   If not \c NULL list of used resources is returned.
+	 * @param dispose  If \c true job information is removed from session
+	 *   at the end of call and further accesses to this job_id will
+	 *   raise #FSD_DRMAA_ERRNO_INVALID_JOB.  Otherwise job data is held.
+	 * @see #wait_for_any_job #wait
+	 */
+	void (*
+	wait_for_single_job)(
+			fsd_drmaa_session_t *self,
+			const char *job_id, const struct timespec *timeout,
+			int *status, fsd_iter_t **rusage, bool dispose
+			);
+
+	/**
+	 * Wait until and job left in session terminates.
+	 * @return  Identifier of waited job.
+	 *   Freeing responsobility is left to the callee.
+	 * @see #wait_for_single_job #wait
+	 */
+	char* (*
+	wait_for_any_job)(
+			fsd_drmaa_session_t *self,
+			const struct timespec *timeout,
+			int *status, fsd_iter_t **rusage,
+			bool dispose
+			);
+
+	void (*
+	wait_for_job_status_change)(
+			fsd_drmaa_session_t *self,
+			fsd_cond_t *wait_condition,
+			fsd_mutex_t *mutex,
+			const struct timespec *timeout
+			);
+
+	void* (*
+	wait_thread)( fsd_drmaa_session_t *self );
+
+	void (*
+	stop_wait_thread)( fsd_drmaa_session_t *self );
+
+	/**
+	 * Make status of all jobs held in session up to date.
+	 */
+	void (*
+	update_all_jobs_status)( fsd_drmaa_session_t *self );
+
+	/** Return list of all jobs within session. */
+	char** (*
+	get_submited_job_ids)(
+			fsd_drmaa_session_t *self
+			);
+
+	/**
+	 * Get job with given identifier.
+	 * @return New reference to job or \c NULL
+	 *   if no job found.
+	 */
+	fsd_job_t* (*
+	get_job)(
+			fsd_drmaa_session_t *self, const char *job_id
+			);
+
+	/**
+	 * Tries to load configuration from following locations in order
+	 * (configuration settings from later locations override
+	 * those from earlier):
+	 * /etc/basename.conf, ~/.basename.conf, $basename_CONF.
+	 */
+	void (*
+	load_configuration)(
+			fsd_drmaa_session_t *self, const char *basename
+			);
+
+	void (*
+	read_configuration)(
+			fsd_drmaa_session_t *self,
+			const char *filename, bool must_exist,
+			const char *configuration, size_t config_len
+			);
+
+	void (*
+	apply_configuration)(
+			fsd_drmaa_session_t *self
+			);
+
+	/** Reference counter. */
+	int ref_cnt;
+
+	/**
+	 * Whether #destroy was called and waits for releasing
+	 * references.  If set pending #wait calls shall
+	 * return with #FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION error.
+	 */
+	bool destroy_requested;
+
+	/**
+	 * Copy of contact string passed to drmaa_init()
+	 * or default contact if drmaa_init() was called with \c NULL.
+	 */
+	char *contact;
+
+	/**
+	 * Jobs submitted within this DRMAA session
+	 * and not disposed yet.
+	 */
+	fsd_job_set_t *jobs;
+
+	/** DRMAA configuration. */
+	fsd_conf_dict_t *configuration;
+
+	/** Queue pooling delay (time delta). */
+	struct timespec pool_delay;
+
+	/**
+	 * Cache job state for number of seconds.
+	 * If positive drmaa_job_ps() returns remembered state without
+	 * communicating with DRM for \a cache_job_state seconds since last
+	 * update.
+	 */
+	int cache_job_state;
+
+	/** Whether to wait for jobs in separate thread. */
+	bool enable_wait_thread;
+
+	/**
+	 * Configuration dictionary which maps
+	 * job categories to native specification.
+	 */
+	fsd_conf_dict_t *job_categories;
+
+	/**
+	 * How to behave when submitted job disappears from DRM queue.
+	 */
+	fsd_missing_jobs_behaviour_t missing_jobs;
+
+	fsd_mutex_t mutex; /**< Mutex for accessing session data. */
+	fsd_cond_t wait_condition;  /**< Conditional for drmaa_wait() */
+	fsd_cond_t destroy_condition;  /**< Conditional for ref_cnt==1 */
+
+	/**
+	 * Mutex for accessing connection to DRM.
+	 *
+	 * To prevent deadlocks #mutex should be acquired first
+	 * when both session data and DRM connection are needed.
+	 */
+	fsd_mutex_t drm_connection_mutex;
+
+	fsd_thread_t wait_thread_handle;
+	bool wait_thread_started;
+	bool wait_thread_run_flag;
+};
+
+
+typedef struct fsd_drmaa_ctx_s {
+	fsd_drmaa_session_t *session;
+	fsd_mutex_t session_mutex;
+	
+} fsd_drmaa_ctx_t;
+
+
+extern fsd_drmaa_ctx_t fsd_drmaa_ctx;
+
+#endif /* __DRMAA_UTILS__SESSION_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/Makefile.am
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/Makefile.am	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/Makefile.am	(revision 77)
@@ -0,0 +1,62 @@
+# $Id: Makefile.am 18 2011-10-12 12:21:55Z mmamonski $
+#
+# PSNC DRMAA 2.0 utilities library
+# Copyright (C) 2012  Poznan Supercomputing and Networking Center
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+
+noinst_LTLIBRARIES = libdrmaa_utils.la
+COMMON_SOURCES = \
+ common.h \
+ compat.h compat.c \
+ conf_impl.h conf_tab.c conf_tab.h conf.c conf.h \
+ drmaa2.h \
+ environ.h environ.c \
+ exception.c exception.h \
+ util.h fsd_util.c \
+ iter.h iter.c \
+ logging.h logging.c \
+ lookup3.c lookup.h \
+ thread.h thread.c \
+ xmalloc.h xmalloc.c
+# job.h fsd_job.c \
+# session.h fsd_session.c \
+# drmaa_util.c drmaa_util.h
+ 
+ 
+ 
+
+
+libdrmaa_utils_la_SOURCES = $(COMMON_SOURCES) \
+ drmaa_base.c drmaa_base.h
+
+
+libdrmaa_utils_la_LDFLAGS = -static
+libdrmaa_utils_la_CPPFLAGS = -fPIC
+
+
+include_HEADERS = drmaa2.h
+
+EXTRA_DIST = conf_tab.y
+
+if DEVELOPER_MODE
+CLEANFILES = $(BUILT_SOURCES)
+endif
+
+
+
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf.h	(revision 77)
@@ -0,0 +1,110 @@
+/* $Id: conf.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__CONF_H
+#define __DRMAA_UTILS__CONF_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/common.h>
+
+typedef enum {
+	FSD_CONF_INTEGER,
+	FSD_CONF_STRING,
+	FSD_CONF_DICT
+} fsd_conf_type_t;
+
+struct fsd_conf_option_s {
+	fsd_conf_type_t type;
+	union {
+		int integer;
+		char *string;
+		fsd_conf_dict_t *dict;
+	} val;
+};
+
+
+/**
+ * Read configuration.
+ */
+fsd_conf_dict_t *
+fsd_conf_read(
+		fsd_conf_dict_t *configuration,
+		const char *filename, bool must_exist,
+		const char *content, size_t content_len
+		);
+
+
+fsd_conf_dict_t *
+fsd_conf_load( const char *filename );
+
+fsd_conf_option_t *
+fsd_conf_option_create( fsd_conf_type_t type, void *value );
+
+void
+fsd_conf_option_destroy( fsd_conf_option_t *option );
+
+fsd_conf_option_t *
+fsd_conf_option_merge( fsd_conf_option_t *lhs, fsd_conf_option_t *rhs );
+
+void
+fsd_conf_option_dump( fsd_conf_option_t *option );
+
+
+
+fsd_conf_dict_t *
+fsd_conf_dict_create(void);
+
+void
+fsd_conf_dict_destroy( fsd_conf_dict_t *dict );
+
+fsd_conf_option_t *
+fsd_conf_dict_get( fsd_conf_dict_t *dict, const char *key );
+
+void
+fsd_conf_dict_set(
+		fsd_conf_dict_t *dict, const char *key, fsd_conf_option_t *value
+		);
+
+fsd_conf_dict_t *
+fsd_conf_dict_merge( fsd_conf_dict_t *lhs, fsd_conf_dict_t *rhs );
+
+void
+fsd_conf_dict_dump( fsd_conf_dict_t *dict );
+
+
+/*
+ * Versions of functions above which do not raise exceptions.
+ * Needed in conf_tab.y
+ */
+
+fsd_conf_option_t *
+fsd_conf_option_create_noraise( fsd_conf_type_t type, void *value );
+
+fsd_conf_dict_t *
+fsd_conf_dict_create_noraise(void);
+
+int
+fsd_conf_dict_set_noraise(
+		fsd_conf_dict_t *dict, const char *key, fsd_conf_option_t *value );
+
+#endif /* __DRMAA_UTILS__CONF_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/logging.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/logging.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/logging.h	(revision 77)
@@ -0,0 +1,100 @@
+/* $Id: logging.h 26 2011-10-17 07:04:33Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__LOGGING_H
+#define __DRMAA_UTILS__LOGGING_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <drmaa_utils/compat.h>
+#include <drmaa_utils/util.h>
+
+#define _log_fmt(level, kind, args) \
+	do { \
+		if( (int)fsd_verbose_level <= level ) \
+			_fsd_log( level, __FILE__, __FUNCTION__, kind, \
+					fsd_asprintf args ); \
+	} while(0)
+
+#define _log_empty(level, kind) \
+	do { \
+		if( (int)fsd_verbose_level <= level ) \
+			_fsd_log( level, __FILE__, __FUNCTION__, kind, NULL ); \
+	} while(0)
+
+#define _log_nop \
+	do { /* nothing */ } while(0)
+
+#ifdef DEBUGGING
+#	define fsd_log_trace(args)   _log_fmt(FSD_LOG_TRACE, _FSD_LOG_MSG, args)
+#	define fsd_log_debug(args)   _log_fmt(FSD_LOG_DEBUG, _FSD_LOG_MSG, args)
+#	define fsd_log_enter(args)   _log_fmt(FSD_LOG_TRACE, _FSD_LOG_ENTER, args)
+#	define fsd_log_return(args)   _log_fmt(FSD_LOG_TRACE, _FSD_LOG_RETURN, args)
+#else /* ! DEBUGGING */
+#	define fsd_log_trace(args)   _log_nop
+#	define fsd_log_debug(args)   _log_nop
+#	define fsd_log_enter(args)   _log_nop
+#	define fsd_log_return(args)  _log_nop
+#endif
+
+#define fsd_log_info(args)     _log_fmt(FSD_LOG_INFO, _FSD_LOG_MSG, args)
+#define fsd_log_warning(args)  _log_fmt(FSD_LOG_WARNING, _FSD_LOG_MSG, args)
+#define fsd_log_error(args)    _log_fmt(FSD_LOG_ERROR, _FSD_LOG_MSG, args)
+#define fsd_log_fatal(args)    _log_fmt(FSD_LOG_FATAL, _FSD_LOG_MSG, args)
+
+enum{ _FSD_LOG_MSG, _FSD_LOG_ENTER, _FSD_LOG_RETURN };
+void _fsd_log( int level, const char *file, const char *function,
+	int kind, char *message );
+
+void fsd_log_fmt( int level, const char *fmt, ... )
+	__attribute__(( format( printf, 2, 3 ) ));
+
+void fsd_log_fmtv( int level, const char *fmt, va_list args );
+
+void fsd_log_stacktrace( int skip, int limit );
+
+/**
+ * Specify place where log messages shall be written.
+ * By default they are written to standard error stream (2).
+ * @param fd   File descriptor to write to.
+ */
+void
+fsd_set_logging_fd( int fd );
+
+typedef enum {
+	FSD_LOG_ALL,
+	FSD_LOG_TRACE,
+	FSD_LOG_DEBUG,
+	FSD_LOG_INFO,
+	FSD_LOG_WARNING,
+	FSD_LOG_ERROR,
+	FSD_LOG_FATAL,
+	FSD_LOG_NONE
+} fsd_verbose_level_t;
+
+void fsd_set_verbosity_level( fsd_verbose_level_t level );
+
+extern fsd_verbose_level_t fsd_verbose_level;
+
+#endif /* __DRMAA_UTILS__LOGGING_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.c	(revision 77)
@@ -0,0 +1,190 @@
+/* $Id: xmalloc.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file xmalloc.c
+ * Memory allocation/deallocation routines.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <drmaa_utils/xmalloc.h>
+#include <drmaa_utils/compat.h>
+#include <drmaa_utils/exception.h>
+#include <drmaa_utils/logging.h>
+
+#ifndef SIZE_T_MAX
+#  define SIZE_T_MAX ((size_t) -1)
+#endif
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: xmalloc.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+void *
+fsd_malloc_( void **p, size_t size )
+{
+	void *ptr = NULL;
+	if( size )
+	 {
+		ptr = malloc( size );
+		if( ptr )
+			memset( ptr, 0, size );
+		else
+		 {
+			*p = NULL;
+			fsd_exc_raise_sys( errno=ENOMEM );
+		 }
+	 }
+	*p = ptr;
+	return ptr;
+}
+
+
+void *
+fsd_calloc_( void **p, size_t n, size_t size )
+{
+	void *ptr = NULL;
+
+	/*fsd_log_enter(("%d", (int)n));*/
+
+	if( n && size )
+	 {
+		if( n <= SIZE_T_MAX / size )
+			ptr = calloc( n, size );
+		if( !ptr )
+		 {
+			*p = NULL;
+			fsd_exc_raise_sys( errno=ENOMEM );
+		 }
+	 }
+	*p = ptr;
+	return ptr;
+}
+
+
+void *
+fsd_realloc_( void **p, size_t size )
+{
+	void *ptr = *p;
+
+	if( size )
+	 {
+		if( ptr )
+			ptr = realloc( ptr, size );
+		else
+			ptr = malloc( size );
+
+		if( ptr != NULL )
+			*p = ptr;
+		else
+			fsd_exc_raise_sys( errno=ENOMEM );
+	 }
+	else if( ptr != NULL )
+	 {
+		free( ptr );
+		*p = ptr = NULL;
+	 }
+
+	return ptr;
+}
+
+
+void
+fsd_free( void *p )
+{
+	if( p )
+		free( p );
+}
+
+
+int
+fsd_malloc_noraise_( void **p, size_t size )
+{
+	int result = 0;
+	void *ptr = NULL;
+	if( size )
+	 {
+		ptr = malloc( size );
+		if( ptr )
+			memset( ptr, 0, size );
+		else
+			result = ENOMEM;
+	 }
+	*p = ptr;
+	return result;
+}
+
+
+int
+fsd_calloc_noraise_( void **p, size_t n, size_t size )
+{
+	int result = 0;
+	void *ptr = NULL;
+	if( n && size )
+	 {
+		if( n <= SIZE_T_MAX / size )
+			ptr = calloc( n, size );
+		if( !ptr )
+			result = ENOMEM;
+	 }
+	*p = ptr;
+	return result;
+}
+
+
+int
+fsd_realloc_noraise_( void **p, size_t size )
+{
+	int result = 0;
+	void *ptr = *p;
+
+	if( size )
+	 {
+		if( ptr )
+			ptr = realloc( ptr, size );
+		else
+			ptr = malloc( size );
+
+		if( ptr != NULL )
+			*p = ptr;
+		else
+			result = ENOMEM;
+	 }
+	else if( ptr != NULL )
+	 {
+		free( ptr );
+		*p = ptr = NULL;
+	 }
+
+	return result;
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/xmalloc.h	(revision 77)
@@ -0,0 +1,88 @@
+/* $Id: xmalloc.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file xmalloc.h
+ * Memory allocation/deallocation routines.
+ */
+
+#ifndef __DRMAA_UTILS__XMALLOC_H
+#define __DRMAA_UTILS__XMALLOC_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/compat.h>
+
+/**
+ * @defgroup xmalloc  Memory allocation/deallocation routines.
+ */
+/* @{ */
+
+
+/**
+ * Allocates <code> sizeof(type) </code> bytes.  Address of block is stored
+ * in @a p.  Upon failure FSD_ERRNO_NO_MEMORY is raised and @a p is NULL.
+ */
+#define fsd_malloc( p, type ) \
+	fsd_malloc_( (void**)(void*)&(p), sizeof(type) )
+
+/**
+ * Allocates <code> n * sizeof(type) </code> bytes of memory and stores
+ * address in \a p.  Allocated block is filled with zeros.  Upon failure
+ * error FSD_ERRNO_NO_MEMORY is raised.
+ * \c NULL is assigned to \a p on error or when <code> n == 0 </code>.
+ */
+#define fsd_calloc( p, n, type ) \
+	fsd_calloc_( (void**)(void*)&(p), (n), sizeof(type) )
+
+#define fsd_realloc( p, n, type ) \
+	fsd_realloc_( (void**)(void*)&(p), (n)*sizeof(type) )
+
+/**
+ * Fress previously allocated memory pointed by @a p.
+ * When <code> p == NULL </code> it does nothing.
+ */
+void fsd_free( void *p );
+
+void *fsd_malloc_( void **p, size_t size );
+void *fsd_calloc_( void **p, size_t n, size_t size );
+void *fsd_realloc_( void **p, size_t size );
+
+
+#define fsd_malloc_noraise( p, type ) \
+	fsd_malloc_noraise_( (void**)(void*)&(p), sizeof(type) )
+
+#define fsd_calloc_noraise( p, n, type ) \
+	fsd_calloc_noraise_( (void**)(void*)&(p), (n), sizeof(type) )
+
+#define fsd_realloc_noraise( p, n, type ) \
+	fsd_realloc_noraise_( (void**)(void*)&(p), (n)*sizeof(type) )
+
+#define fsd_free_noraise( p )  (fsd_free(p), 0)
+
+int fsd_malloc_noraise_( void **p, size_t size );
+int fsd_calloc_noraise_( void **p, size_t n, size_t size );
+int fsd_realloc_noraise_( void **p, size_t size );
+
+/* @} */
+
+#endif /* __DRMAA_UTILS__XMALLOC_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/fsd_job.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/fsd_job.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/fsd_job.c	(revision 77)
@@ -0,0 +1,461 @@
+/* $Id: fsd_job.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include <drmaa_utils/drmaa.h>
+#include <drmaa_utils/iter.h>
+#include <drmaa_utils/job.h>
+#include <drmaa_utils/lookup3.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: fsd_job.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+static void fsd_job_release( fsd_job_t *self );
+static void fsd_job_destroy( fsd_job_t *self );
+static void fsd_job_control( fsd_job_t *self, int action );
+static void fsd_job_update_status( fsd_job_t *self );
+static void fsd_job_get_termination_status( fsd_job_t *self,
+			int *status, fsd_iter_t **rusage_out );
+static void fsd_job_on_missing( fsd_job_t *self );
+
+fsd_job_t *
+fsd_job_new( char *job_id )
+{
+	fsd_job_t *volatile self = NULL;
+	fsd_log_enter(( "(%s)", job_id ));
+	TRY
+	 {
+		fsd_malloc( self, fsd_job_t );
+		self->release = fsd_job_release;
+		self->destroy = fsd_job_destroy;
+		self->control = fsd_job_control;
+		self->update_status = fsd_job_update_status;
+		self->get_termination_status = fsd_job_get_termination_status;
+		self->on_missing = fsd_job_on_missing;
+		self->next              = NULL;
+		self->ref_cnt           = 1;
+		self->job_id            = job_id;
+		self->session           = NULL;
+		self->last_update_time  = 0;
+		self->flags             = 0;
+		self->state             = DRMAA_PS_UNDETERMINED;
+		self->exit_status       = 0;
+		self->submit_time       = 0;
+		self->start_time        = 0;
+		self->end_time          = 0;
+		self->cpu_usage         = 0;
+		self->mem_usage         = 0;
+		self->vmem_usage        = 0;
+		self->walltime          = 0;
+		self->execution_hosts   = NULL;
+		self->queue				= NULL;
+		self->project			= NULL;
+		fsd_mutex_init( &self->mutex );
+		fsd_cond_init( &self->status_cond );
+		fsd_cond_init( &self->destroy_cond );
+		fsd_mutex_lock( &self->mutex );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( self )
+			self->destroy( self );
+		else
+			fsd_free( job_id );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+	fsd_log_return(( "=%p: ref_cnt=%d [lock %s]",
+				(void*)self, self->ref_cnt, self->job_id ));
+	return self;
+}
+
+
+void
+fsd_job_release( fsd_job_t *self )
+{
+	bool destroy;
+	fsd_log_enter(( "(%p={job_id=%s, ref_cnt=%d}) [unlock %s]",
+				(void*)self, self->job_id, self->ref_cnt, self->job_id ));
+	fsd_assert( self->ref_cnt > 0 );
+	destroy = ( --(self->ref_cnt) == 0 );
+	fsd_mutex_unlock( &self->mutex );
+	if( destroy )
+		self->destroy( self );
+	fsd_log_return(( "" ));
+}
+
+
+void
+fsd_job_destroy( fsd_job_t *self )
+{
+	fsd_log_enter(( "(%p={job_id=%s})", (void*)self, self->job_id ));
+	fsd_cond_destroy( &self->status_cond );
+	fsd_cond_destroy( &self->destroy_cond );
+	fsd_mutex_destroy( &self->mutex );
+	fsd_free( self->job_id );
+	fsd_free( self->execution_hosts );
+	fsd_free( self->queue );
+	fsd_free( self->project );
+	fsd_free( self );
+	fsd_log_return(( "" ));
+}
+
+
+void
+fsd_job_control( fsd_job_t *self, int action )
+{
+	fsd_exc_raise_code( FSD_ERRNO_NOT_IMPLEMENTED );
+}
+
+void
+fsd_job_update_status( fsd_job_t *self )
+{
+	fsd_exc_raise_code( FSD_ERRNO_NOT_IMPLEMENTED );
+}
+
+void
+fsd_job_get_termination_status( fsd_job_t *self,
+			int *status, fsd_iter_t **rusage_out )
+{
+	fsd_iter_t* volatile rusage = NULL;
+
+	TRY
+	 {
+		if( rusage_out )
+		 {
+			rusage = fsd_iter_new( NULL, 0 );
+			rusage->append( rusage, fsd_asprintf(
+						"submission_time=%ld", (long)self->submit_time ) );
+			rusage->append( rusage, fsd_asprintf(
+						"start_time=%ld", (long)self->start_time ) );
+			rusage->append( rusage, fsd_asprintf(
+						"end_time=%ld", (long)self->end_time ) );
+			rusage->append( rusage, fsd_asprintf(
+						"cpu=%ld", self->cpu_usage ) );
+			rusage->append( rusage, fsd_asprintf(
+						"mem=%ld", self->mem_usage ) );
+			rusage->append( rusage, fsd_asprintf(
+						"vmem=%ld", self->vmem_usage ) );
+			rusage->append( rusage, fsd_asprintf(
+						"walltime=%ld", self->walltime ) );
+			rusage->append( rusage, fsd_asprintf(
+						"hosts=%s", self->execution_hosts ) );
+
+			if (self->queue) {
+				rusage->append( rusage, fsd_asprintf("queue=%s", self->queue ) );
+			}
+
+			if (self->project) {
+				rusage->append( rusage, fsd_asprintf("project=%s", self->project ) );
+			}
+		 }
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( rusage )
+			rusage->destroy( rusage );
+		if( rusage_out )
+			*rusage_out = NULL;
+		fsd_exc_reraise();
+	 }
+	ELSE
+	 {
+		if( status )
+			*status = self->exit_status;
+		if( rusage_out )
+			*rusage_out = rusage;
+	 }
+	END_TRY
+}
+
+void
+fsd_job_on_missing( fsd_job_t *self )
+{
+	fsd_log_warning(( "job %s missing from DRM queue", self->job_id ));
+}
+
+
+static void
+fsd_job_set_destroy( fsd_job_set_t *self );
+static void
+fsd_job_set_add( fsd_job_set_t *self, fsd_job_t *job );
+static void
+fsd_job_set_remove( fsd_job_set_t *self, fsd_job_t *job );
+static fsd_job_t *
+fsd_job_set_get( fsd_job_set_t *self, const char *job_id );
+static bool
+fsd_job_set_empty( fsd_job_set_t *self );
+static fsd_job_t *
+fsd_job_set_find_terminated( fsd_job_set_t *self );
+static char **
+fsd_job_set_get_all_job_ids( fsd_job_set_t *self );
+static void fsd_job_set_signal_all( fsd_job_set_t *self );
+
+
+fsd_job_set_t *
+fsd_job_set_new(void)
+{
+	fsd_job_set_t *volatile self = NULL;
+	const size_t initial_size = 1024;
+
+	fsd_log_enter(( "()" ));
+	TRY
+	 {
+		fsd_malloc( self, fsd_job_set_t );
+		self->destroy = fsd_job_set_destroy;
+		self->add = fsd_job_set_add;
+		self->remove = fsd_job_set_remove;
+		self->get = fsd_job_set_get;
+		self->empty = fsd_job_set_empty;
+		self->find_terminated = fsd_job_set_find_terminated;
+		self->get_all_job_ids = fsd_job_set_get_all_job_ids;
+		self->signal_all = fsd_job_set_signal_all;
+		self->tab = NULL;
+		self->n_jobs = 0;
+		fsd_calloc( self->tab, initial_size, fsd_job_t* );
+		self->tab_size = initial_size;
+		self->tab_mask = self->tab_size - 1;
+		fsd_mutex_init( &self->mutex );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( self )
+		 {
+			fsd_free( self->tab );
+			fsd_free( self );
+		 }
+		fsd_exc_reraise();
+	 }
+	END_TRY
+
+	fsd_log_return(( " =%p", (void*)self ));
+	return self;
+}
+
+
+void
+fsd_job_set_destroy( fsd_job_set_t *self )
+{
+	unsigned i;
+	fsd_job_t *j;
+
+	fsd_log_enter(( "()" ));
+	for( i = 0;  i < self->tab_size;  i++ )
+		for( j = self->tab[i];  j != NULL;  )
+		 {
+			fsd_job_t *job = j;
+			j = j->next;
+			fsd_mutex_lock( &job->mutex );
+			job->release( job );
+		 }
+	fsd_free( self->tab );
+	fsd_free( self );
+	fsd_log_return(( "" ));
+}
+
+
+void
+fsd_job_set_add( fsd_job_set_t *self, fsd_job_t *job )
+{
+	uint32_t h;
+	fsd_log_enter(( "(job=%p, job_id=%s)", (void*)job, job->job_id ));
+	fsd_mutex_lock( &self->mutex );
+	h = hashstr( job->job_id, strlen(job->job_id), 0 );
+	h &= self->tab_mask;
+	job->next = self->tab[ h ];
+	self->tab[ h ] = job;
+	self->n_jobs++;
+	job->ref_cnt++;
+	fsd_mutex_unlock( &self->mutex );
+	fsd_log_return(( ": job->ref_cnt=%d", job->ref_cnt ));
+}
+
+
+void
+fsd_job_set_remove( fsd_job_set_t *self, fsd_job_t *job )
+{
+	fsd_job_t **pjob = NULL;
+	uint32_t h;
+
+	fsd_log_enter(( "(job_id=%s)", job->job_id ));
+	fsd_mutex_lock( &self->mutex );
+	TRY
+	 {
+		h = hashstr( job->job_id, strlen(job->job_id), 0 );
+		h &= self->tab_mask;
+		for( pjob = &self->tab[ h ];  *pjob;  pjob = &(*pjob)->next )
+		 {
+			if( *pjob == job )
+				break;
+		 }
+		if( *pjob )
+		 {
+			*pjob = (*pjob)->next;
+			job->next = NULL;
+			self->n_jobs--;
+			job->ref_cnt--;
+		 }
+		else
+			fsd_exc_raise_code( FSD_DRMAA_ERRNO_INVALID_JOB );
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &self->mutex ); }
+	END_TRY
+	fsd_log_return(( ": job->ref_cnt=%d", job->ref_cnt ));
+}
+
+
+fsd_job_t *
+fsd_job_set_get( fsd_job_set_t *self, const char *job_id )
+{
+	uint32_t h;
+	fsd_job_t *job = NULL;
+
+	fsd_log_enter(( "(job_id=%s)", job_id ));
+	fsd_mutex_lock( &self->mutex );
+	h = hashstr( job_id, strlen(job_id), 0 );
+	h &= self->tab_mask;
+	for( job = self->tab[ h ];  job;  job = job->next )
+		if( !strcmp( job->job_id, job_id ) )
+			break;
+	if( job )
+	 {
+		fsd_mutex_lock( &job->mutex );
+		fsd_assert( !(job->flags & FSD_JOB_DISPOSED) );
+		job->ref_cnt ++;
+	 }
+	fsd_mutex_unlock( &self->mutex );
+	if( job )
+		fsd_log_return(( "(job_id=%s) =%p: ref_cnt=%d [lock %s]",
+					job_id, (void*)job, job->ref_cnt, job->job_id ));
+	else
+		fsd_log_return(( "(job_id=%s) =NULL", job_id ));
+	return job;
+}
+
+
+bool
+fsd_job_set_empty( fsd_job_set_t *self )
+{
+	return self->n_jobs == 0;
+}
+
+
+fsd_job_t *
+fsd_job_set_find_terminated( fsd_job_set_t *self )
+{
+	fsd_job_t *job = NULL;
+	size_t i;
+	fsd_mutex_t* volatile mutex = & self->mutex;
+
+	fsd_log_enter(( "()" ));
+	fsd_mutex_lock( mutex );
+	TRY
+	 {
+		for( i = 0;  i < self->tab_size;  i++ )
+			for( job = self->tab[ i ];  job;  job = job->next )
+				if( job->state >= DRMAA_PS_DONE )
+					goto found;
+found:
+		if( job )
+		 {
+			fsd_mutex_lock( &job->mutex );
+			fsd_assert( !(job->flags & FSD_JOB_DISPOSED) );
+			job->ref_cnt ++;
+		 }
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( mutex ); }
+	END_TRY
+	if( job )
+		fsd_log_return(( "() =%p: job_id=%s, ref_cnt=%d [lock %s]",
+					(void*)job, job->job_id, job->ref_cnt, job->job_id ));
+	else
+		fsd_log_return(( "() =%p", (void*)job ));
+	return job;
+}
+
+
+char **
+fsd_job_set_get_all_job_ids( fsd_job_set_t *self )
+{
+	fsd_job_t *job = NULL;
+	char** volatile job_ids = NULL;
+	/* size_t n_jobs = 0, capacity = 0; */
+	size_t i;
+	unsigned j = 0;
+	fsd_mutex_t* volatile mutex = & self->mutex;
+
+	fsd_log_enter(( "" ));
+	fsd_mutex_lock( mutex );
+	TRY
+	 {
+		fsd_calloc( job_ids, self->n_jobs+1, char* );
+		for( i = 0;  i < self->tab_size;  i++ )
+			for( job = self->tab[ i ];  job;  job = job->next )
+				job_ids[ j++ ] = fsd_strdup( job->job_id );
+		fsd_realloc( job_ids, j+1, char* );
+	 }
+	FINALLY
+	 {
+		fsd_mutex_unlock( mutex );
+		if( fsd_exc_get() )
+			fsd_free_vector( job_ids );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =%p", (void*)job_ids ));
+	return job_ids;
+}
+
+
+void
+fsd_job_set_signal_all( fsd_job_set_t *self )
+{
+	fsd_job_t *volatile job = NULL;
+	fsd_mutex_t *volatile mutex = & self->mutex;
+
+	fsd_log_enter(( "" ));
+	fsd_mutex_lock( mutex );
+	TRY
+	 {
+		volatile size_t i;
+		for( i = 0;  i < self->tab_size;  i++ )
+			for( job = self->tab[ i ];  job;  job = job->next )
+			 {
+				fsd_mutex_lock( &job->mutex );
+				TRY{ fsd_cond_broadcast( &job->status_cond ); }
+				FINALLY{ fsd_mutex_unlock( &job->mutex ); }
+				END_TRY
+			 }
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( mutex ); }
+	END_TRY
+
+	fsd_log_return(( "" ));
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/thread.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/thread.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/thread.c	(revision 77)
@@ -0,0 +1,418 @@
+/* $Id: thread.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file thread.c
+ * Implementation of recursive mutexes for systems without native support
+ * for it.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/thread.h>
+#include <drmaa_utils/common.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef HAVE_GETTID
+#include <sys/types.h>
+#include <sys/syscall.h>
+pid_t gettid(void)
+{
+	return (pid_t)syscall( __NR_gettid );
+}
+#endif
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: thread.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+void
+fsd_thread_create( fsd_thread_t *thread, void* (*func)(void*), void *arg )
+{
+	int errno_ = 0;
+	errno_ = pthread_create( thread, NULL, func, arg );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_thread_join( fsd_thread_t th, void **thread_return )
+{
+	int errno_ = 0;
+	errno_ = pthread_join( th, thread_return );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_thread_detach( fsd_thread_t th )
+{
+	int errno_ = 0;
+	errno_ = pthread_detach( th );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+
+#if HAVE_RECURSIVE_MUTEXES
+
+void
+fsd_mutex_init( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	pthread_mutexattr_t attr;
+	do {
+		errno_ = pthread_mutexattr_init( &attr );
+		if( errno_ )  break;
+		errno_ = pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE_NP );
+		if( errno_ )  break;
+		errno_ = pthread_mutex_init( mutex, &attr );
+		if( errno_ )  break;
+		errno_ = pthread_mutexattr_destroy( &attr );
+	} while( false );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_mutex_destroy( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_mutex_destroy( mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+bool
+fsd_mutex_lock( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_mutex_lock( mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+	return true;
+}
+
+bool
+fsd_mutex_unlock( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_mutex_unlock( mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+	return false;
+}
+
+bool
+fsd_mutex_trylock( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_mutex_trylock( mutex );
+	switch( errno_ )
+	 {
+		case 0:
+			return true;
+		case EBUSY:
+			return false;
+		default:
+			fsd_exc_raise_sys( errno_ );
+	 }
+}
+
+int
+fsd_mutex_unlock_times( fsd_mutex_t *mutex )
+{
+	int count = 0;
+	int errno_ = 0;
+	while( errno_ == 0 )
+	 {
+		errno_ = pthread_mutex_unlock( mutex );
+		if( !errno_ )
+			count++;
+	 }
+	if( errno_ != EPERM  ||  count == 0 )
+		fsd_exc_raise_sys( errno_ );
+	return count;
+}
+
+void
+fsd_cond_init( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_init( cond, NULL );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_destroy( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_destroy( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_signal( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_signal( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_broadcast( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_broadcast( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_wait( fsd_cond_t *cond, fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_wait( cond, mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+bool
+fsd_cond_timedwait( fsd_cond_t *cond, fsd_mutex_t *mutex,
+		const struct timespec *abstime )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_timedwait( cond, mutex, abstime );
+	switch( errno_ )
+	 {
+		case 0:
+			return true;
+		case ETIMEDOUT:
+			return false;
+		default:
+			fsd_exc_raise_sys( errno_ );
+	 }
+}
+
+#else /* ! HAVE_RECURSIVE_MUTEXES */
+
+void
+fsd_mutex_init( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	mutex->owner = (pthread_t)-1;
+	mutex->acquired = 0;
+	errno_ = pthread_mutex_init( &mutex->mutex, NULL );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_mutex_destroy( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	errno_ = pthread_mutex_destroy( &mutex->mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+bool
+fsd_mutex_lock( fsd_mutex_t *mutex )
+{
+	/* Note: The order of checks is significant. */
+	if( mutex->acquired  &&  pthread_equal( mutex->owner, pthread_self() ) )
+		mutex->acquired ++;
+	else
+	 {
+		int errno_ = 0;
+		errno_ = pthread_mutex_lock( &mutex->mutex );
+		if( errno_ == 0 )
+		 {
+			mutex->owner    = pthread_self();
+			mutex->acquired = 1;
+		 }
+		else
+			fsd_exc_raise_sys( errno_ );
+	 }
+	return true;
+}
+
+bool
+fsd_mutex_unlock( fsd_mutex_t *mutex )
+{
+	fsd_assert( mutex->acquired
+			&&  pthread_equal( mutex->owner, pthread_self() ) );
+	if( -- (mutex->acquired) == 0 )
+	 {
+		int errno_ = 0;
+		errno_ = pthread_mutex_unlock( &mutex->mutex );
+		if( errno_ )
+			fsd_exc_raise_sys( errno_ );
+	 }
+	return false;
+}
+
+bool
+fsd_mutex_trylock( fsd_mutex_t *mutex )
+{
+	if( mutex->acquired  &&  pthread_equal( mutex->owner, pthread_self() ) )
+	 {
+		mutex->acquired ++;
+		return true;
+	 }
+	else
+	 {
+		int errno_ = 0;
+		errno_ = pthread_mutex_trylock( &mutex->mutex );
+		switch( errno_ )
+		 {
+			case 0:
+				mutex->owner    = pthread_self();
+				mutex->acquired = 1;
+				return true;
+			case ETIMEDOUT:
+				return false;
+			default:
+				fsd_exc_raise_sys( errno_ );
+		 }
+	 }
+}
+
+int
+fsd_mutex_unlock_times( fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	int count = 0;
+	fsd_assert( mutex->acquired
+			&&  pthread_equal( mutex->owner, pthread_self() ) );
+	count = mutex->acquired;
+	mutex->acquired = 0;
+	errno_ = pthread_mutex_unlock( &mutex->mutex );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+	return count;
+}
+
+void
+fsd_cond_init( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_init( cond, NULL );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_destroy( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_destroy( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_signal( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_signal( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_broadcast( fsd_cond_t *cond )
+{
+	int errno_ = 0;
+	errno_ = pthread_cond_broadcast( cond );
+	if( errno_ )
+		fsd_exc_raise_sys( errno_ );
+}
+
+void
+fsd_cond_wait( fsd_cond_t *cond, fsd_mutex_t *mutex )
+{
+	int errno_ = 0;
+	int acquired_save = mutex->acquired;
+	fsd_assert( mutex->acquired
+			&&  pthread_equal( mutex->owner, pthread_self() ) );
+	errno_ = pthread_cond_wait( cond, &mutex->mutex );
+	if( errno_ == 0 )
+	 {
+		mutex->owner = pthread_self();
+		mutex->acquired = acquired_save;
+	 }
+	else
+		fsd_exc_raise_sys( errno_ );
+}
+
+bool
+fsd_cond_timedwait( fsd_cond_t *cond, fsd_mutex_t *mutex,
+		const struct timespec *abstime )
+{
+	int errno_ = 0;
+	int acquired_save = mutex->acquired;
+	fsd_assert( mutex->acquired
+			&&  pthread_equal( mutex->owner, pthread_self() ) );
+	errno_ = pthread_cond_timedwait( cond, &mutex->mutex, abstime );
+	switch( errno_ )
+	 {
+		case 0:
+			mutex->owner = pthread_self();
+			mutex->acquired = acquired_save;
+			return true;
+		case ETIMEDOUT:
+			mutex->owner = pthread_self();
+			mutex->acquired = acquired_save;
+			return false;
+		default:
+			fsd_exc_raise_sys( errno_ );
+	 }
+}
+
+#endif /* ! HAVE_RECURSIVE_MUTEXES */
+
+
+
+int
+fsd_thread_id(void)
+{
+#if HAVE_GETTID
+	/*
+	 * On Linux 2.6 (with NPTL) getpid() returns
+	 * same value for all threads in single process.
+	 */
+	return (int)gettid();
+#else
+	return (int)getpid();
+#endif
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/fsd_util.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/fsd_util.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/fsd_util.c	(revision 77)
@@ -0,0 +1,703 @@
+/* $Id: fsd_util.c 31 2011-11-28 14:09:06Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/util.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: fsd_util.c 31 2011-11-28 14:09:06Z mmamonski $";
+#endif
+
+
+static char *
+fsd_expand_printf_ph( const char *fmt );
+
+
+void
+fsd_free_vector( char **vector )
+{
+	char **i;
+	if( vector == NULL )
+		return;
+	for( i = vector;  *i != NULL;  i++ )
+		fsd_free( *i );
+	fsd_free( vector );
+}
+
+
+char **
+fsd_copy_vector( const char *const * vector )
+{
+	unsigned n_items, i;
+	char** volatile buf = NULL;
+	char** volatile result = NULL;
+
+	TRY
+	 {
+		if( vector )
+			for( n_items = 0;  vector[ n_items ] != NULL;  n_items++ ) {}
+		else
+			n_items = 0;
+
+		fsd_calloc( buf, n_items+1, char* );
+		for( i = 0;  i < n_items;  i++ )
+			buf[i] = fsd_strdup( vector[i] );
+	 }
+	ELSE
+	 { result = buf;  buf = NULL; }
+	FINALLY
+	 { fsd_free_vector( buf ); }
+	END_TRY
+
+	return result;
+}
+
+
+char *
+fsd_replace( char *str, const char *placeholder, const char *value )
+{
+	size_t ph_len, v_len;
+	char *found = NULL;
+	char* volatile s = str;
+
+	if( str == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INTERNAL_ERROR );
+
+	ph_len = strlen( placeholder );
+	v_len  = strlen( value );
+
+	do {
+		size_t s_len;
+		s_len = strlen( s );
+		found = strstr( s, placeholder );
+		if( found )
+		 {
+			char* volatile result;
+			size_t pos = found - s;
+			TRY
+			 {
+				fsd_calloc( result, s_len - ph_len + v_len + 1, char );
+				memcpy( result, s, pos );
+				memcpy( result+pos, value, v_len );
+				memcpy( result+pos+v_len, s+pos+ph_len, s_len-pos-ph_len );
+				result[ s_len-ph_len+v_len ] = 0;
+			 }
+			FINALLY
+			 {
+				fsd_free( s );
+				s = result;
+			 }
+			END_TRY
+		 }
+	} while( found );
+
+	return s;
+}
+
+
+char *
+fsd_explode( const char *const *vector, char glue, int n )
+{
+	char* volatile result = NULL;
+	char* volatile buf = NULL;
+	char *s;
+	const char *const *i;
+	unsigned idx, max=(unsigned)n;
+	size_t size =0;
+
+	TRY
+	 {
+		for( i = vector, idx = 0;  idx < max && *i != NULL;  i++, idx++ )
+		 {
+			if( i != vector )
+				size++;
+			size += strlen(*i);
+		 }
+
+		fsd_calloc( buf, size+1, char );
+		s = buf;
+		for( i = vector, idx = 0;  idx < max && *i != NULL;  i++, idx++ )
+		 {
+			if( i != vector )
+				*s++ = glue;
+			strcpy( s, *i );
+			s += strlen( *i );
+		 }
+	 }
+	ELSE
+	 { result = buf;  buf = NULL; }
+	FINALLY
+	 { fsd_free( buf ); }
+	END_TRY
+
+	return result;
+}
+
+
+char *
+fsd_strdup( const char *s )
+{
+	char *result;
+	if( s == NULL )
+		return NULL;
+	result = strdup( s );
+	if( result == NULL )
+		fsd_exc_raise_sys( ENOMEM );
+	return result;
+}
+
+
+char *
+fsd_strndup( const char *s, size_t n )
+{
+	char *result;
+	if( s == NULL )
+		return NULL;
+	result = strndup( s, n );
+	if( result == NULL )
+		fsd_exc_raise_sys( ENOMEM );
+	return result;
+}
+
+
+int
+fsd_atoi( const char *string )
+{
+	const char *s = string;
+	int sign = +1;
+	int v = 0;
+
+	while( isspace(*(const unsigned char*)s) )
+		s++;
+	switch( *s )
+	 {
+		case '+':  sign = +1;  s++;  break;
+		case '-':  sign = -1;  s++;  break;
+		default:  break;
+	 }
+	while( isspace(*(const unsigned char*)s) )
+		s++;
+	if( '0' <= *s  &&  *s <= '9' )
+	 {
+		while( '0' <= *s  &&  *s <= '9' )
+		 {
+			if( v > INT_MAX/10 )
+				goto range_error;
+			v *= 10;
+			v += *s++ - '0';
+			if( v < 0 )
+				goto range_error;
+		 }
+	 }
+	else
+		goto nan_error;
+
+	while( isspace(*(const unsigned char*)s) )
+		s++;
+	if( *s != '\0' )
+		goto nan_error;
+
+	return sign * v;
+
+range_error:
+	fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT,
+			"value out of range: %s", string );
+	return 0;
+
+nan_error:
+		fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT,
+				"not an number: %s", string );
+	return 0;
+}
+
+
+void
+fsd_str_append(
+		bool *truncated,
+		char **p, char *end,
+		const char *fmt, ...
+		)
+{
+	va_list args;
+	va_start( args, fmt );
+	*p += fsd_vsnprintf( truncated, *p, end-*p, fmt, args );
+	va_end( args );
+}
+
+
+size_t
+fsd_snprintf(
+		bool *truncated,
+		char *str, size_t size,
+		const char *fmt, ...
+		)
+{
+	va_list args;
+	size_t result;
+	va_start( args, fmt );
+	result = fsd_vsnprintf( truncated, str, size, fmt, args );
+	va_end( args );
+	return result;
+}
+
+
+size_t
+fsd_vsnprintf(
+		bool *truncated,
+		char *str, size_t size,
+		const char *fmt, va_list args
+		)
+{
+	int n;
+	char *fmt_buf = NULL;
+	fmt_buf = fsd_expand_printf_ph( fmt );
+	if( fmt_buf )
+		fmt = fmt_buf;
+	n = vsnprintf( str, size, fmt, args );
+	if( fmt_buf )
+		fsd_free( fmt_buf );
+	if( 0 <= n  &&  (size_t)n < size )
+	 {}
+	else
+	 {
+		str[size-1] = '\0';
+		*truncated = true;
+	 }
+	return n;
+}
+
+
+char *
+fsd_asprintf( const char *fmt, ... )
+{
+	va_list args;
+	char *result = NULL;
+	va_start( args, fmt );
+	result = fsd_vasprintf( fmt, args );
+	va_end( args );
+	return result;
+}
+
+
+char *
+fsd_vasprintf( const char *fmt, va_list args )
+{
+	char *result = NULL;
+	char *fmt_buf = NULL;
+	int rc;
+	fmt_buf = fsd_expand_printf_ph( fmt );
+	if( fmt_buf )
+		fmt = fmt_buf;
+	rc = vasprintf( &result, fmt, args );
+	if( fmt_buf )
+		fsd_free( fmt_buf );
+	if( rc == -1 )
+		fsd_exc_raise_sys( ENOMEM );
+	return result;
+}
+
+
+/**
+ * ``%m`` placeholder which is a glibc extension
+ * can be safely used in fsd_*printf functions.
+ */
+char *
+fsd_expand_printf_ph( const char *fmt )
+{
+	char* volatile result = NULL;
+
+	if( strstr(fmt, "%m") == NULL )
+		return result;
+
+	TRY
+	 {
+		const char *pos;
+		while( (pos = strstr(fmt, "%m")) != NULL
+				&&  (pos == fmt  ||  pos[-1] != '%') )
+		 {
+			char* volatile errno_msg = NULL;
+			volatile bool own_errno_msg = false;
+			TRY
+			 {
+				char *buf = NULL;
+				size_t fmt_len = strlen(fmt);
+				size_t ph_pos = pos - fmt;
+				size_t errno_msg_len;
+				errno_msg = fsd_astrerror( errno, (bool*)&own_errno_msg );
+				errno_msg_len = strlen(errno_msg);
+				fsd_calloc( buf, fmt_len-2+errno_msg_len+1, char );
+				/* replace ``%m`` with strerror(errno) */
+				strncat( buf, fmt, ph_pos );
+				strcat( buf+ph_pos, errno_msg );
+				strcat( buf+ph_pos+errno_msg_len, fmt+ph_pos+2 );
+				fsd_free( result );
+				fmt = result = buf;
+			 }
+			FINALLY
+			 {
+				if( errno_msg && own_errno_msg )
+					fsd_free( errno_msg );
+			 }
+			END_TRY
+		 }
+	 }
+	EXCEPT_DEFAULT
+	 {
+		fsd_free( result );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+
+	return result;
+}
+
+
+const char *
+fsd_strerror_r( int errnum, char *buffer, size_t buffer_size )
+{
+#	ifdef HAVE_DECL_STRERROR_R
+#		ifdef _GNU_SOURCE
+			return strerror_r( errnum, buffer, buffer_size );
+#		else
+			strerror_r( errnum, buffer, buffer_size );
+			return buffer;
+#		endif /* !_GNU_SOURCE */
+#	else /* assume strerror is thread safe -- returned string is constant */
+		return strerror(errnum);
+#	endif /* ! HAVE_STRERROR_R */
+}
+
+
+char *
+fsd_astrerror( int errnum, bool *malloced )
+{
+#ifdef HAVE_DECL_STRERROR_R
+	char *buffer = NULL;
+	size_t buffer_size = 0;
+	char *result = NULL;
+
+	do {
+		if( buffer_size == 0 )
+			buffer_size = 1024;
+		else
+			buffer_size *= 2;
+		fsd_realloc( buffer, buffer_size, char );
+#		ifdef _GNU_SOURCE
+		result = strerror_r( errnum, buffer, buffer_size );
+		if( result == buffer && strlen(result)+1 == buffer_size )
+			continue;
+#		else
+		if( strerror_r( errnum, buffer, buffer_size ) && errno == ERANGE )
+		 {
+			result = buffer;
+			continue;
+		 }
+#		endif /* !_GNU_SOURCE */
+	} while( false );
+	*malloced = (buffer == result);
+	if( buffer != result )
+		fsd_free( buffer );
+	return result;
+#else /* ! HAVE_DECL_STRERROR_R */
+	/* assume strerror is thread safe -- returned string is constant */
+	*malloced = false;
+	return strerror(errnum);
+#endif /* ! HAVE_DECL_STRERROR_R */
+}
+
+
+void
+fsd_get_time( struct timespec *ts )
+{
+	struct timeval tv;
+	int rc;
+	rc = gettimeofday( &tv, NULL );
+	if( rc )
+		fsd_exc_raise_sys( 0 );
+	else
+	 {
+		ts->tv_sec = tv.tv_sec;
+		ts->tv_nsec = 1000 * tv.tv_usec;
+	 }
+}
+
+
+void
+fsd_ts_add( struct timespec *a, const struct timespec *b )
+{
+	const int nano = 1000000000;
+	a->tv_sec += b->tv_sec;
+	a->tv_nsec += b->tv_nsec;
+	if( a->tv_nsec >= nano )
+	 {
+		a->tv_nsec -= nano;
+		a->tv_sec ++;
+	 }
+}
+
+
+int
+fsd_ts_cmp( const struct timespec *a, const struct timespec *b )
+{
+	if( a->tv_sec != b->tv_sec )
+		return a->tv_sec - b->tv_sec;
+	else
+		return a->tv_nsec - b->tv_nsec;
+}
+
+
+void
+fsd_read_file(
+		const char *filename, bool must_exist,
+		char **content, size_t *length
+		)
+{
+	volatile int fd = -1;
+	char* volatile buffer = NULL;
+	size_t size = 0;
+	size_t capacity = 0;
+	ssize_t n_read;
+
+	TRY
+	 {
+		*content = NULL;
+		*length = 0;
+
+		fd = open( filename, O_RDONLY );
+		if( fd == -1 )
+		 {
+			if( errno==ENOENT && !must_exist )
+			 {
+				*content = NULL;
+				*length = 0;
+			 }
+			else
+				fsd_exc_raise_sys( 0 );
+		 }
+		else
+		 {
+			do {
+				capacity = size + 1024;
+				fsd_realloc( buffer, capacity, char );
+				n_read = read( fd, buffer, capacity-size );
+				if( n_read == (ssize_t)-1 )
+					fsd_exc_raise_sys( 0 );
+				else
+					size += n_read;
+			} while( n_read != 0 );
+
+			fsd_realloc( buffer, size+1, char );
+			buffer[ size ] = '\0';
+		 }
+	 }
+	ELSE
+	 {
+		*content = buffer;  buffer = NULL;
+		*length = size;
+	 }
+	FINALLY
+	 {
+		fsd_free( buffer );
+		if( fd >= 0 )
+			close( fd );
+	 }
+	END_TRY
+}
+
+
+char *
+fsd_getcwd(void)
+{
+	char* volatile buffer = NULL;
+	char* volatile result = NULL;
+	size_t size = 64;
+
+	TRY
+	 {
+		fsd_calloc( buffer, size, char );
+		while( true )
+		 {
+			char *result = getcwd( buffer, size );
+			if( result != NULL )
+				break;
+			else if( errno == ERANGE )
+			 {
+				size *= 2;
+				fsd_realloc( buffer, size, char );
+			 }
+			else
+				fsd_exc_raise_sys( 0 );
+		 }
+		fsd_realloc( buffer, strlen(buffer)+1, char );
+	 }
+	ELSE
+	 { result = buffer;  buffer = NULL; }
+	FINALLY
+	 { fsd_free( buffer ); }
+	END_TRY
+
+	return result;
+}
+
+char *
+fsd_readline(FILE *f)
+{
+	char* volatile buffer = NULL;
+	char* volatile result = NULL;
+	size_t size = 1024;
+	int ch = '\0';
+	int index = 0;
+
+	TRY
+	 {
+		fsd_calloc( buffer, size + 1, char );
+
+		errno = 0; /* reset errno as getc seems not to do this 
+		and it would be inpossible to distinc between EOF and an error*/
+
+		while( (ch = getc(f)) != EOF) /* getc is buffered internally */
+		 {
+			if (ch == '\n')
+				break;
+
+			if( index >= (int)size )
+			 {
+				size *= 2;
+				fsd_realloc( buffer, size + 1, char );
+			 }
+
+			buffer[index++] = (char)ch;
+		 }
+
+		if ( (ch == '\n') /* end of line */ || (ch == EOF && !errno) /* true EOF */)
+		 {
+			if (index == 0)
+			 {
+				result = NULL; /*nothing read = return NULL */
+			 }
+			else
+			 {
+				buffer[index]= '\0'; /* just in case - calloc memset to 0 */
+				result = fsd_strdup(buffer);
+			 }
+		 }
+		else if (ch == EOF && errno)
+		 {
+			fsd_exc_raise_sys( 0 );
+		 }
+		else
+		 {
+			fsd_assert(0); /*not reached */
+		 }
+
+	 }
+	FINALLY
+	 { fsd_free( buffer ); }
+	END_TRY
+
+	return result;
+}
+
+
+const char *
+fsd_strsignal( int signum )
+{
+#define DETECT_SIG( signame ) \
+	case signame:  return #signame;
+	switch( signum )
+	 {
+		/* signals described by POSIX.1 */
+		DETECT_SIG( SIGHUP  )
+		DETECT_SIG( SIGINT	)
+		DETECT_SIG( SIGQUIT )
+		DETECT_SIG( SIGILL	)
+		DETECT_SIG( SIGABRT )
+		DETECT_SIG( SIGFPE	)
+		DETECT_SIG( SIGKILL )
+		DETECT_SIG( SIGSEGV )
+		DETECT_SIG( SIGPIPE )
+		DETECT_SIG( SIGALRM )
+		DETECT_SIG( SIGTERM )
+		DETECT_SIG( SIGUSR1 )
+		DETECT_SIG( SIGUSR2 )
+		DETECT_SIG( SIGCHLD )
+		DETECT_SIG( SIGCONT )
+		DETECT_SIG( SIGSTOP )
+		DETECT_SIG( SIGTSTP )
+		DETECT_SIG( SIGTTIN )
+		DETECT_SIG( SIGTTOU )
+		/* signals described in SUSv2 and SUSv3 / POSIX 1003.1-2001 */
+#ifdef SIGBUS
+		DETECT_SIG( SIGBUS    )
+#endif
+#ifdef SIGPOLL
+		DETECT_SIG( SIGPOLL	  )
+#endif
+#ifdef SIGPROF
+		DETECT_SIG( SIGPROF	  )
+#endif
+#ifdef SIGSYS
+		DETECT_SIG( SIGSYS	  )
+#endif
+#ifdef SIGTRAP
+		DETECT_SIG( SIGTRAP	  )
+#endif
+#ifdef SIGURG
+		DETECT_SIG( SIGURG	  )
+#endif
+#ifdef SIGVTALRM
+		DETECT_SIG( SIGVTALRM )
+#endif
+#ifdef SIGXCPU
+		DETECT_SIG( SIGXCPU	  )
+#endif
+#ifdef SIGXFSZ
+		DETECT_SIG( SIGXFSZ	  )
+#endif
+		default:
+#		ifdef HAVE_SYS_SIGLIST
+			return sys_siglist[signum];
+#		else
+			return "unknown signal?!";
+#		endif
+			break;
+	 }
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf_impl.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf_impl.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf_impl.h	(revision 77)
@@ -0,0 +1,81 @@
+/* $Id: conf_impl.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__CONF_IMPL_H
+#define __DRMAA_UTILS__CONF_IMPL_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/conf.h>
+
+typedef struct fsd_conf_parser_s fsd_conf_parser_t;
+typedef struct fsd_conf_lexer_s fsd_conf_lexer_t;
+union YYSTYPE;
+struct YYLTYPE;
+typedef unsigned char uchar;
+
+
+int
+fsd_conf_parse( fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer );
+
+int
+fsd_conf_lex( union YYSTYPE *lvalp, struct YYLTYPE *locp,
+		fsd_conf_lexer_t *lexer );
+
+void
+fsd_conf_error(
+		struct YYLTYPE *locp,
+		fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer,
+		const char *fmt, ...
+		);
+
+
+/** DRMAA configuration file parser data. */
+struct fsd_conf_parser_s {
+	fsd_conf_lexer_t *lexer;
+
+	/** Parsing result - root of syntax tree. */
+	fsd_conf_dict_t *result;
+
+	int n_errors;  /**< Number of parse/lexical errors. */
+	char **errors;
+};
+
+/** DRMAA configuration file lexical analyzer data. */
+struct fsd_conf_lexer_s {
+	fsd_conf_parser_t *parser;  /**< Parser which use this lexer. */
+	const char *filename; /**< Name of configuration file. */
+
+	const uchar *buffer;  /**< Entire content of parsed configuration file. */
+	size_t buflen;  /**< Length of \a buffer. */
+
+	const uchar *pos;  /**< Current position of lexical analyzer. */
+	int lineno; /**< Current line number (counted from 1). */
+	const uchar *cline;  /**< Points to first character (byte) of current line. */
+};
+
+typedef struct fsd_conf_pair_s {
+	char *key;
+	fsd_conf_option_t *value;
+} fsd_conf_pair_t;
+
+#endif /* __DRMAA_UTILS__CONF_IMPL_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.c	(revision 77)
@@ -0,0 +1,1737 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names.  */
+#define yyparse fsd_conf_parse
+#define yylex   fsd_conf_lex
+#define yyerror fsd_conf_error
+#define yylval  fsd_conf_lval
+#define yychar  fsd_conf_char
+#define yydebug fsd_conf_debug
+#define yynerrs fsd_conf_nerrs
+#define yylloc fsd_conf_lloc
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INTEGER = 258,
+     STRING = 259,
+     LEXER_ERROR = 260
+   };
+#endif
+/* Tokens.  */
+#define INTEGER 258
+#define STRING 259
+#define LEXER_ERROR 260
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 20 "conf_tab.y"
+
+#ifdef HAVE_MALLOC_H
+#       include <malloc.h>
+#endif
+#include <drmaa_utils/conf_impl.h>
+#include <drmaa_utils/conf_tab.h>
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 36 "conf_tab.y"
+{
+	int integer;
+	char *string;
+	fsd_conf_option_t *option;
+	fsd_conf_dict_t *dictionary;
+	fsd_conf_pair_t pair;
+}
+/* Line 193 of yacc.c.  */
+#line 130 "conf_tab.c"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 155 "conf_tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  11
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   17
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  10
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  8
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  14
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  19
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   260
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     8,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     9,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     6,     2,     7,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     5,     7,     9,    13,    15,    18,    19,
+      21,    25,    29,    31,    33
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      11,     0,    -1,    12,    -1,    13,    -1,    14,    -1,     6,
+      14,     7,    -1,    15,    -1,    15,     8,    -1,    -1,    16,
+      -1,    15,     8,    16,    -1,     4,     9,    17,    -1,     3,
+      -1,     4,    -1,    13,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint8 yyrline[] =
+{
+       0,    58,    58,    62,    63,    67,    71,    72,    73,    80,
+      95,   106,   110,   119,   128
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "INTEGER", "STRING", "LEXER_ERROR",
+  "'{'", "'}'", "','", "':'", "$accept", "start", "conf", "dict",
+  "dict_body", "pair_list", "pair", "value", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   123,   125,    44,    58
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    10,    11,    12,    12,    13,    14,    14,    14,    15,
+      15,    16,    17,    17,    17
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     1,     1,     1,     3,     1,     2,     0,     1,
+       3,     3,     1,     1,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       8,     0,     8,     0,     2,     3,     4,     6,     9,     0,
+       0,     1,     7,    12,    13,    14,    11,     5,    10
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     3,     4,     5,     6,     7,     8,    16
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -5
+static const yytype_int8 yypact[] =
+{
+      -2,    -4,     2,     7,    -5,    -5,    -5,     0,    -5,    -3,
+       3,    -5,     2,    -5,    -5,    -5,    -5,    -5,    -5
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+      -5,    -5,    -5,     4,     9,    -5,     5,    -5
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+      13,    14,     1,     2,     2,     9,     1,    11,    12,     0,
+      17,    10,     0,    15,     0,     0,     0,    18
+};
+
+static const yytype_int8 yycheck[] =
+{
+       3,     4,     4,     6,     6,     9,     4,     0,     8,    -1,
+       7,     2,    -1,     9,    -1,    -1,    -1,    12
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     4,     6,    11,    12,    13,    14,    15,    16,     9,
+      14,     0,     8,     3,     4,    13,    17,     7,    16
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (&yylloc, parser, lexer, YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, lexer)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, Location, parser, lexer); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser, lexer)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    fsd_conf_parser_t *parser;
+    fsd_conf_lexer_t *lexer;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+  YYUSE (parser);
+  YYUSE (lexer);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parser, lexer)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    fsd_conf_parser_t *parser;
+    fsd_conf_lexer_t *lexer;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser, lexer);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, parser, lexer)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+    fsd_conf_parser_t *parser;
+    fsd_conf_lexer_t *lexer;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , parser, lexer);
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, yylsp, Rule, parser, lexer); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, parser, lexer)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+    fsd_conf_parser_t *parser;
+    fsd_conf_lexer_t *lexer;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+  YYUSE (parser);
+  YYUSE (lexer);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+      case 4: /* "STRING" */
+#line 51 "conf_tab.y"
+	{ free((yyvaluep->string)); };
+#line 1065 "conf_tab.c"
+	break;
+      case 12: /* "conf" */
+#line 47 "conf_tab.y"
+	{ fsd_conf_dict_destroy((yyvaluep->dictionary)); };
+#line 1070 "conf_tab.c"
+	break;
+      case 13: /* "dict" */
+#line 47 "conf_tab.y"
+	{ fsd_conf_dict_destroy((yyvaluep->dictionary)); };
+#line 1075 "conf_tab.c"
+	break;
+      case 14: /* "dict_body" */
+#line 47 "conf_tab.y"
+	{ fsd_conf_dict_destroy((yyvaluep->dictionary)); };
+#line 1080 "conf_tab.c"
+	break;
+      case 15: /* "pair_list" */
+#line 47 "conf_tab.y"
+	{ fsd_conf_dict_destroy((yyvaluep->dictionary)); };
+#line 1085 "conf_tab.c"
+	break;
+      case 17: /* "value" */
+#line 45 "conf_tab.y"
+	{ fsd_conf_option_destroy((yyvaluep->option)); };
+#line 1090 "conf_tab.c"
+	break;
+
+      default:
+	break;
+    }
+}
+
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (fsd_conf_parser_t *parser, fsd_conf_lexer_t *lexer)
+#else
+int
+yyparse (parser, lexer)
+    fsd_conf_parser_t *parser;
+    fsd_conf_lexer_t *lexer;
+#endif
+#endif
+{
+  /* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
+YYLTYPE yylloc;
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended.  */
+  YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+	yyls = yyls1;
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+	YYSTACK_RELOCATE (yyls);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 58 "conf_tab.y"
+    { parser->result = (yyvsp[(1) - (1)].dictionary);  (yyval.dictionary) = NULL; ;}
+    break;
+
+  case 5:
+#line 67 "conf_tab.y"
+    { (yyval.dictionary) = (yyvsp[(2) - (3)].dictionary); ;}
+    break;
+
+  case 6:
+#line 71 "conf_tab.y"
+    { (yyval.dictionary) = (yyvsp[(1) - (1)].dictionary); ;}
+    break;
+
+  case 7:
+#line 72 "conf_tab.y"
+    { (yyval.dictionary) = (yyvsp[(1) - (2)].dictionary); ;}
+    break;
+
+  case 8:
+#line 73 "conf_tab.y"
+    {
+		(yyval.dictionary) = fsd_conf_dict_create_noraise();
+		if( (yyval.dictionary) == NULL )  YYABORT;
+	;}
+    break;
+
+  case 9:
+#line 81 "conf_tab.y"
+    {
+			fsd_conf_dict_t *dict = NULL;
+			int rc;
+			dict = fsd_conf_dict_create_noraise();
+			if( dict == NULL )
+				YYABORT;
+			rc = fsd_conf_dict_set_noraise( dict, (yyvsp[(1) - (1)].pair).key, (yyvsp[(1) - (1)].pair).value );
+			if( rc )
+			 {
+				fsd_conf_dict_destroy( dict );
+				YYABORT;
+			 }
+			(yyval.dictionary) = dict;
+		 ;}
+    break;
+
+  case 10:
+#line 96 "conf_tab.y"
+    {
+			int rc;
+			rc = fsd_conf_dict_set_noraise( (yyvsp[(1) - (3)].dictionary), (yyvsp[(3) - (3)].pair).key, (yyvsp[(3) - (3)].pair).value );
+			if( rc )
+				YYABORT;
+			(yyval.dictionary) = (yyvsp[(1) - (3)].dictionary); /* explicit no op */
+		 ;}
+    break;
+
+  case 11:
+#line 106 "conf_tab.y"
+    { (yyval.pair).key = (yyvsp[(1) - (3)].string);  (yyval.pair).value = (yyvsp[(3) - (3)].option); ;}
+    break;
+
+  case 12:
+#line 111 "conf_tab.y"
+    {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_INTEGER, &(yyvsp[(1) - (1)].integer) );
+			if( o )
+				(yyval.option) = o;
+			else
+				YYABORT;
+		 ;}
+    break;
+
+  case 13:
+#line 120 "conf_tab.y"
+    {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_STRING, (yyvsp[(1) - (1)].string) );
+			if( o )
+				(yyval.option) = o;
+			else
+				YYABORT;
+		 ;}
+    break;
+
+  case 14:
+#line 129 "conf_tab.y"
+    {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_DICT, (yyvsp[(1) - (1)].dictionary) );
+			if( o )
+				(yyval.option) = o;
+			else
+				YYABORT;
+		 ;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1513 "conf_tab.c"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (&yylloc, parser, lexer, YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (&yylloc, parser, lexer, yymsg);
+	  }
+	else
+	  {
+	    yyerror (&yylloc, parser, lexer, YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, &yylloc, parser, lexer);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp, yylsp, parser, lexer);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the look-ahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&yylloc, parser, lexer, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc, parser, lexer);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp, yylsp, parser, lexer);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+#line 139 "conf_tab.y"
+
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/thread.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/thread.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/thread.h	(revision 77)
@@ -0,0 +1,125 @@
+/* $Id: thread.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file thread.h
+ *
+ * Thread and synchronization primitives.
+ */
+
+#ifndef __DRMAA_UTILS__THREAD_H
+#define __DRMAA_UTILS__THREAD_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <pthread.h>
+#include <time.h>
+
+#include <drmaa_utils/compat.h>
+
+/**
+ * @defgroup recursive_mutex  Recursive mutexes implementation.
+ * It uses recursive mutexes if supplied by POSIX threads library
+ * or implements it over plain mutexes.
+ */
+/* @{ */
+
+#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
+#	define HAVE_RECURSIVE_MUTEXES 1
+#else
+#	define HAVE_RECURSIVE_MUTEXES 0
+#endif /* ! PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
+
+
+#if HAVE_RECURSIVE_MUTEXES
+
+	typedef pthread_mutex_t fsd_mutex_t;
+#	define FSD_MUTEX_INITIALIZER  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+	typedef pthread_cond_t  fsd_cond_t;
+#	define FSD_COND_INITIALIZER  PTHREAD_COND_INITAILIZER
+
+#else /* !HAVE_RECURSIVE_MUTEXES */
+
+	/**
+	 * Recursive mutex build on top of non-recursive mutex
+	 * (used when recursive mutexes are not provided by POSIX
+	 * thread library).
+	 */
+	typedef struct fsd_mutex_s {
+		pthread_mutex_t mutex; /**< Non-recursive mutex. */
+		pthread_t       owner; /**< Thread which owns critical section. */
+		int             acquired; /**< How many times
+			owning thread acquired this mutex. */
+	} fsd_mutex_t;
+#	define FSD_MUTEX_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, (pthread_t)-1, 0 }
+	typedef pthread_cond_t  fsd_cond_t;
+#	define FSD_COND_INITIALIZER  PTHREAD_COND_INITAILIZER
+
+#endif /* ! HAVE_RECURSIVE_MUTEXES */
+
+
+/** pthread_mutex_init wrapper.  Initializes recursive mutex. */
+void fsd_mutex_init     ( fsd_mutex_t *mutex );
+void fsd_mutex_destroy  ( fsd_mutex_t *mutex );
+bool fsd_mutex_lock     ( fsd_mutex_t *mutex );
+bool fsd_mutex_unlock   ( fsd_mutex_t *mutex );
+bool fsd_mutex_trylock  ( fsd_mutex_t *mutex );
+
+/**
+ * Try to unlock mutex as many times as possible
+ * returning the count of locks previously granted
+ * to current thread.
+ */
+int fsd_mutex_unlock_times( fsd_mutex_t *mutex );
+
+void fsd_cond_init      ( fsd_cond_t *cond );
+void fsd_cond_destroy   ( fsd_cond_t *cond );
+void fsd_cond_signal    ( fsd_cond_t *cond );
+void fsd_cond_broadcast ( fsd_cond_t *cond );
+void fsd_cond_wait      ( fsd_cond_t *cond, fsd_mutex_t *mutex );
+bool fsd_cond_timedwait ( fsd_cond_t *cond, fsd_mutex_t *mutex,
+		const struct timespec *abstime );
+/* @} */
+
+
+/**
+ * @defgroup thread  Wrapper around POSIX thread functions.
+ */
+/* @{ */
+typedef pthread_t fsd_thread_t;
+/** pthread_create wrapper */
+void fsd_thread_create( fsd_thread_t *thread, void* (*func)(void*), void *arg );
+#define fsd_thread_self    pthraed_self
+#define fsd_thraed_equal   pthread_equal
+#define fsd_thread_exit    pthread_exit
+/** pthread_join wrapper */
+void fsd_thread_join( fsd_thread_t th, void **thread_return );
+/** pthread_detach wrapper */
+void fsd_thread_detach( fsd_thread_t th );
+/* void fsd_thread_cancel( fsd_thread_t th ); */
+/* @} */
+
+
+/** Returns thread identifier. */
+int fsd_thread_id(void);
+
+#endif /* __DRMAA_UTILS__THREAD_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.c	(revision 77)
@@ -0,0 +1,1385 @@
+/* $Id: drmaa_base.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  FedStage DRMAA utilities library
+ *  Copyright (C) 2006-2008  FedStage Systems
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file drmaa_base.c
+ * DRM independant part of DRMAA library.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <drmaa_utils/drmaa2.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: drmaa_base.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+#define DRMAA_API_BEGIN \
+	volatile int rc = -1; \
+	TRY \
+	 {
+#define DRMAA_API_END \
+		rc = DRMAA_ERRNO_SUCCESS; \
+	 } \
+	EXCEPT_DEFAULT \
+	 { \
+		const fsd_exc_t *e = fsd_exc_get(); \
+		rc = fsd_drmaa_code( e->code(e) ); \
+		fsd_log_return(( "=%d: %s", rc, e->message(e) )); \
+	 } \
+	END_TRY \
+	if( rc < 0 ) \
+	 { \
+		rc = DRMAA_ERRNO_NO_MEMORY; \
+	 } \
+	return rc;
+
+
+#define DRMAA_API_BEGIN_PTR \
+	volatile int rc = -1; \
+	TRY \
+	 {
+#define DRMAA_API_END_PTR \
+		rc = DRMAA_ERRNO_SUCCESS; \
+	 } \
+	EXCEPT_DEFAULT \
+	 { \
+		const fsd_exc_t *e = fsd_exc_get(); \
+		rc = fsd_drmaa_code( e->code(e) ); \
+		fsd_log_return(( "=%d: %s", rc, e->message(e) )); \
+	 } \
+	END_TRY \
+	if( rc < 0 ) \
+	 { \
+		rc = DRMAA_ERRNO_NO_MEMORY; \
+	 } \
+	return NULL;
+
+
+
+void drmaa2_string_free(drmaa2_string *ptr)
+{
+
+}
+
+drmaa2_error
+drmaa2_lasterror(void)
+{
+
+}
+
+drmaa2_string
+drmaa2_lasterror_text(void)
+{
+
+}
+
+drmaa2_list
+drmaa2_list_create(const drmaa2_listtype t, const drmaa2_list_entryfree callback)
+{
+
+}
+
+void
+drmaa2_list_free(drmaa2_list * l)
+{
+
+
+}
+
+const void *
+drmaa2_list_get(const drmaa2_list l, long pos)
+{
+
+}
+
+drmaa2_error
+drmaa2_list_add(drmaa2_list l, const void * value)
+{
+
+}
+
+drmaa2_error
+drmaa2_list_del(drmaa2_list l, long pos)
+{
+
+}
+
+long
+drmaa2_list_size(const drmaa2_list l)
+{
+
+
+}
+
+
+drmaa2_dict
+drmaa2_dict_create (const drmaa2_dict_entryfree free_callback)
+{
+
+
+}
+
+void drmaa2_dict_free(drmaa2_dict * d)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_dict_list(const drmaa2_dict d)
+{
+
+}
+
+drmaa2_bool
+drmaa2_dict_has(const drmaa2_dict d, const char * key)
+{
+
+}
+
+const char *
+drmaa2_dict_get(const drmaa2_dict d, const char * key)
+{
+
+}
+
+drmaa2_error
+drmaa2_dict_del(drmaa2_dict d, const char * key)
+{
+
+
+}
+
+drmaa2_error
+drmaa2_dict_set(drmaa2_dict d, const char * key, const char * val)
+{
+
+}
+
+
+drmaa2_jinfo
+drmaa2_jinfo_create(void)
+{
+
+}
+
+void
+drmaa2_jinfo_free(drmaa2_jinfo * ji)
+{
+
+}
+
+void drmaa2_slotinfo_free(drmaa2_slotinfo * si)
+{
+
+}
+
+
+void drmaa2_rinfo_free(drmaa2_rinfo * ri)
+{
+
+}
+
+drmaa2_jtemplate
+drmaa2_jtemplate_create(void)
+{
+
+}
+
+
+void
+drmaa2_jtemplate_free(drmaa2_jtemplate * jt)
+{
+
+}
+
+
+drmaa2_rtemplate
+drmaa2_rtemplate_create(void)
+{
+
+}
+
+void
+drmaa2_rtemplate_free(drmaa2_rtemplate * rt)
+{
+
+}
+
+void
+drmaa2_notification_free(drmaa2_notification * n)
+{
+
+}
+
+void
+drmaa2_queueinfo_free(drmaa2_queueinfo * qi)
+{
+
+}
+
+void
+drmaa2_version_free(drmaa2_version * v)
+{
+
+}
+
+
+void
+drmaa2_machineinfo_free(drmaa2_machineinfo * mi)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_jtemplate_impl_spec(void)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_jinfo_impl_spec(void)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_rtemplate_impl_spec(void)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_rinfo_impl_spec(void)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_queueinfo_impl_spec(void)
+{
+
+
+}
+
+drmaa2_string_list
+drmaa2_machineinfo_impl_spec(void)
+{
+
+
+}
+
+drmaa2_string_list
+drmaa2_notification_impl_spec(void)
+{
+
+}
+
+drmaa2_string
+drmaa2_get_instance_value(const void * instance, const char * name)
+{
+
+}
+
+drmaa2_string
+drmaa2_describe_attribute(const void * instance, const char * name)
+{
+
+}
+
+drmaa2_error
+drmaa2_set_instance_value(void * instance, const char * name, const char * value)
+{
+
+}
+
+void
+drmaa2_jsession_free(drmaa2_jsession * js)
+{
+
+}
+
+void drmaa2_rsession_free(drmaa2_rsession * rs)
+{
+
+}
+
+void
+drmaa2_msession_free(drmaa2_msession * ms)
+{
+
+}
+
+void
+drmaa2_j_free(drmaa2_j * j)
+{
+
+}
+
+void
+drmaa2_jarray_free(drmaa2_jarray * ja)
+{
+
+
+}
+
+void drmaa2_r_free(drmaa2_r * r)
+{
+
+}
+
+drmaa2_string
+drmaa2_rsession_get_contact(const drmaa2_rsession rs)
+{
+
+}
+
+drmaa2_string
+drmaa2_rsession_get_session_name(const drmaa2_rsession rs)
+{
+
+}
+
+drmaa2_r
+drmaa2_rsession_get_reservation(const drmaa2_rsession rs, const drmaa2_string reservationId)
+{
+
+}
+
+drmaa2_r
+drmaa2_rsession_request_reservation(const drmaa2_rsession rs, const drmaa2_rtemplate rt)
+{
+
+}
+
+drmaa2_r_list
+drmaa2_rsession_get_reservations(const drmaa2_rsession rs)
+{
+
+}
+
+drmaa2_string
+drmaa2_r_get_id(const drmaa2_r r)
+{
+
+}
+
+drmaa2_string
+drmaa2_r_get_session_name(const drmaa2_r r)
+{
+
+}
+
+drmaa2_rtemplate
+drmaa2_r_get_reservation_template (const drmaa2_r r)
+{
+
+}
+
+drmaa2_rinfo
+drmaa2_r_get_info(const drmaa2_r r)
+{
+
+}
+
+drmaa2_error
+drmaa2_r_terminate(drmaa2_r r)
+{
+
+}
+
+drmaa2_string
+drmaa2_jarray_get_id(const drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_j_list
+drmaa2_jarray_get_jobs(const drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_string
+drmaa2_jarray_get_session_name(const drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_jtemplate
+drmaa2_jarray_get_job_template(const drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_error drmaa2_jarray_suspend(drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_error drmaa2_jarray_resume(drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_error drmaa2_jarray_hold(drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_error drmaa2_jarray_release(drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_error
+drmaa2_jarray_terminate(drmaa2_jarray ja)
+{
+
+}
+
+drmaa2_string
+drmaa2_jsession_get_contact(const drmaa2_jsession js)
+{
+
+}
+
+
+drmaa2_string drmaa2_jsession_get_session_name(const drmaa2_jsession js)
+{
+
+}
+
+drmaa2_string_list
+drmaa2_jsession_get_job_categories(const drmaa2_jsession js)
+{
+
+}
+
+drmaa2_j_list
+drmaa2_jsession_get_jobs(const drmaa2_jsession js, const drmaa2_jinfo filter)
+{
+
+
+}
+
+drmaa2_jarray
+drmaa2_jsession_get_job_array(const drmaa2_jsession js, const drmaa2_string jobarrayId)
+{
+
+}
+
+drmaa2_j
+drmaa2_jsession_run_job(const drmaa2_jsession js, const drmaa2_jtemplate jt)
+{
+
+}
+
+drmaa2_jarray
+drmaa2_jsession_run_bulk_jobs(const drmaa2_jsession js, const drmaa2_jtemplate jt, unsigned long begin_index, unsigned long end_index, unsigned long step, unsigned long max_parallel)
+{
+
+}
+
+drmaa2_j
+drmaa2_jsession_wait_any_started(const drmaa2_jsession js, const drmaa2_j_list l, const time_t timeout)
+{
+
+}
+
+drmaa2_j drmaa2_jsession_wait_any_terminated(const drmaa2_jsession js, const drmaa2_j_list l, const time_t timeout)
+{
+
+}
+
+drmaa2_string
+drmaa2_j_get_id(const drmaa2_j j)
+{
+
+}
+
+drmaa2_string
+drmaa2_j_get_session_name(const drmaa2_j j)
+{
+
+}
+
+drmaa2_jtemplate
+drmaa2_j_get_jt(const drmaa2_j j)
+{
+
+}
+
+drmaa2_error
+drmaa2_j_suspend(drmaa2_j j)
+{
+
+}
+
+drmaa2_error
+drmaa2_j_resume(drmaa2_j j)
+{
+
+}
+
+drmaa2_error
+drmaa2_j_hold(drmaa2_j j)
+{
+
+}
+
+drmaa2_error
+drmaa2_j_release(drmaa2_j j)
+{
+}
+
+drmaa2_error
+drmaa2_j_terminate(drmaa2_j j)
+{
+}
+
+drmaa2_jstate
+drmaa2_j_get_state(const drmaa2_j j, drmaa2_string * substate)
+{
+}
+
+drmaa2_jinfo
+drmaa2_j_get_info(const drmaa2_j j)
+{
+}
+
+drmaa2_error
+drmaa2_j_wait_started(const drmaa2_j j, const time_t timeout)
+{
+}
+
+drmaa2_error
+drmaa2_j_wait_terminated(const drmaa2_j j, const time_t timeout)
+{
+}
+
+
+drmaa2_r_list
+drmaa2_msession_get_all_reservations(const drmaa2_msession ms)
+{
+}
+
+drmaa2_j_list
+drmaa2_msession_get_all_jobs(const drmaa2_msession ms, const drmaa2_jinfo filter)
+{
+}
+
+drmaa2_queueinfo_list
+drmaa2_msession_get_all_queues(const drmaa2_msession ms, const drmaa2_string_list names)
+{
+}
+
+drmaa2_machineinfo_list
+drmaa2_msession_get_all_machines(const drmaa2_msession ms, const drmaa2_string_list names)
+{
+}
+
+drmaa2_string
+drmaa2_get_drms_name (void)
+{
+}
+
+drmaa2_version
+drmaa2_get_drms_version (void)
+{
+}
+
+drmaa2_string
+drmaa2_get_drmaa_name (void)
+{
+}
+
+drmaa2_version
+drmaa2_get_drmaa_version (void)
+{
+}
+
+drmaa2_bool
+drmaa2_supports (const drmaa2_capability c)
+{
+}
+
+drmaa2_jsession
+drmaa2_create_jsession(const char * session_name, const char * contact)
+{
+}
+
+drmaa2_rsession
+drmaa2_create_rsession(const char * session_name, const char * contact)
+{
+}
+
+drmaa2_jsession
+drmaa2_open_jsession(const char * session_name)
+{
+}
+
+drmaa2_rsession
+drmaa2_open_rsession(const char * session_name)
+{
+}
+
+drmaa2_msession
+drmaa2_open_msession(const char * session_name)
+{
+}
+
+drmaa2_error
+drmaa2_close_jsession(drmaa2_jsession js)
+{
+}
+
+drmaa2_error
+drmaa2_close_rsession(drmaa2_rsession rs)
+{
+}
+
+drmaa2_error
+drmaa2_close_msession(drmaa2_msession ms)
+{
+}
+
+drmaa2_error
+drmaa2_destroy_jsession(const char * session_name)
+{
+}
+
+drmaa2_error
+drmaa2_destroy_rsession(const char * session_name)
+{
+}
+
+drmaa2_string_list
+drmaa2_get_jsession_names(void)
+{
+}
+
+drmaa2_string_list
+drmaa2_get_rsession_names(void)
+{
+}
+
+drmaa2_error
+drmaa2_register_event_notification(const drmaa2_callback callback)
+{
+}
+
+
+
+
+#if 0
+
+int
+drmaa_init(
+		const char *contact,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "(contact=%s)", contact ));
+
+	fsd_mutex_lock( &global->session_mutex );
+	TRY
+	 {
+		if( global->session != NULL )
+			fsd_exc_raise_code( FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION );
+		global->session = global->new_session( global, contact );
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &global->session_mutex ); }
+	END_TRY
+
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_exit( char *error_diagnosis, size_t error_diag_len )
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "()" ));
+
+	fsd_mutex_lock( &global->session_mutex );
+	TRY
+	 {
+		if( global->session != NULL )
+		 {
+			global->session->destroy( global->session );
+			global->session = NULL;
+		 }
+		else
+		 {
+			fsd_exc_raise_code( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION );
+		 }
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &global->session_mutex ); }
+	END_TRY
+
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_allocate_job_template(
+		drmaa_job_template_t **p_jt,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter((""));
+	*p_jt = (drmaa_job_template_t*)global->new_job_template( global );
+	fsd_log_return(( " =0: jt=%p", (void*)*p_jt ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_delete_job_template(
+		drmaa_job_template_t *drmaa_jt,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_template_t *jt = (fsd_template_t*)drmaa_jt;
+	fsd_log_enter(( "(%p)", (void*)jt ));
+	if( jt != NULL )
+		jt->destroy( jt );
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_set_attribute(
+		drmaa_job_template_t *drmaa_jt,
+		const char *name, const char *value,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_template_t *jt = (fsd_template_t*)drmaa_jt;
+	fsd_log_enter(( "(jt=%p, name='%s', value='%s')",
+				(void*)drmaa_jt, name, value ));
+	if( jt != NULL  &&  name != NULL )
+		jt->set_attr( jt, name, value );
+	else
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_attribute(
+	drmaa_job_template_t *drmaa_jt,
+	const char *name, char *value, size_t value_len,
+	char *error_diagnosis, size_t error_diag_len
+	)
+{
+	DRMAA_API_BEGIN
+	fsd_template_t *jt = (fsd_template_t*)drmaa_jt;
+	const char *v = NULL;
+	fsd_log_enter(( "(jt=%p, name='%s')", (void*)drmaa_jt, name ));
+	if( jt == NULL || name == NULL || value == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+	v = jt->get_attr( jt, name );
+	if( v == NULL )
+		v = "";
+	strlcpy( value, v, value_len );
+	fsd_log_return(( " =0: '%s'", value ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_set_vector_attribute(
+		drmaa_job_template_t *drmaa_jt,
+		const char *name, const char *value[],
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_template_t *jt = (fsd_template_t*)drmaa_jt;
+	fsd_log_enter(( "(jt=%p, name='%s', value=...)",
+				(void*)drmaa_jt, name ));
+	if( jt == NULL || name == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+	jt->set_v_attr( jt, name, value );
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_vector_attribute(
+		drmaa_job_template_t *drmaa_jt,
+		const char *name, drmaa_attr_values_t **out_values,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_template_t *jt = (fsd_template_t*)drmaa_jt;
+
+	fsd_log_enter(( "(jt=%p, name='%s')", (void*)drmaa_jt, name ));
+	if( jt == NULL || name == NULL || out_values == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+	*out_values = NULL;
+	*out_values = (drmaa_attr_values_t*)fsd_iter_new(
+			fsd_copy_vector( jt->get_v_attr( jt, name ) ), -1 );
+	fsd_log_return(( " =0" ));
+
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_attribute_names(
+		drmaa_attr_names_t **values,
+		char *error_diagnosis, size_t error_diag_len )
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	*values = (drmaa_attr_names_t*)global->get_attribute_names( global );
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_vector_attribute_names(
+		drmaa_attr_names_t **values,
+		char *error_diagnosis, size_t error_diag_len )
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	*values = (drmaa_attr_names_t*)global->get_vector_attribute_names( global );
+	DRMAA_API_END
+}
+
+
+#define iter_function(name, type) \
+int drmaa_get_next_##name( type *values, char *value, size_t value_len ) \
+{ \
+	char error_diagnosis[1]; \
+	size_t error_diag_len = sizeof(error_diagnosis); \
+	DRMAA_API_BEGIN \
+	fsd_iter_t *iter = (fsd_iter_t*)values; \
+	strlcpy( value, iter->next(iter), value_len ); \
+	DRMAA_API_END \
+} \
+int drmaa_get_num_##name##s( type *values, size_t *size ) \
+{ \
+	char error_diagnosis[1]; \
+	size_t error_diag_len = sizeof(error_diagnosis); \
+	DRMAA_API_BEGIN \
+	fsd_iter_t *iter = (fsd_iter_t*)values; \
+	*size = iter->len(iter); \
+	DRMAA_API_END \
+} \
+void drmaa_release_##name##s( type *values ) \
+{ \
+	fsd_iter_t *iter = (fsd_iter_t*)values; \
+	iter->destroy(iter); \
+}
+
+iter_function(attr_name, drmaa_attr_names_t)
+iter_function(attr_value, drmaa_attr_values_t)
+iter_function(job_id, drmaa_job_ids_t)
+
+#undef iter_function
+
+
+int
+drmaa_control(
+		const char *job_id, int action,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+
+	fsd_log_enter(( "(job_id=%s, action=%s)",
+				job_id, drmaa_control_to_str(action) ));
+
+	if( job_id == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		session->control_job( session, job_id, action );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+
+int
+drmaa_job_ps(
+		const char *job_id, int *remote_ps,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+
+	fsd_log_enter(( "(job_id=%s)", job_id ));
+	if( job_id == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		session->job_ps( session, job_id, remote_ps );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+
+	fsd_log_return(( "(job_id=%s) =0: remote_ps=%s (0x%02x)",
+				job_id, drmaa_job_ps_to_str(*remote_ps), *remote_ps ));
+	DRMAA_API_END
+}
+
+
+
+int
+drmaa_run_job(
+		char *job_id, size_t job_id_len,
+		const drmaa_job_template_t *jt,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+	char *volatile job_id_buf = NULL;
+	fsd_log_enter(( "(jt=%p)", (void*)jt ));
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		job_id_buf = session->run_job( session, (fsd_template_t*)jt ),
+		strlcpy( job_id, job_id_buf, job_id_len );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+		fsd_free( job_id_buf );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =0: job_id=%s", job_id ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_run_bulk_jobs(
+		drmaa_job_ids_t **job_ids,
+		const drmaa_job_template_t *jt,
+		int start, int end, int incr,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+	fsd_log_enter(( "(jt=%p, start=%d, end=%d, incr=%d)",
+		(void*)jt, start, end, incr ));
+	TRY
+	 {
+		if( incr > 0 )
+		 {
+			if( !(0 < start  &&  start <= end) )
+				fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+		 }
+		else if( incr < 0 )
+		 {
+			if( !(start >= end  &&  end > 0) )
+				fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+		 }
+		else
+			fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+
+		session = fsd_drmaa_session_get();
+		*job_ids = (drmaa_job_ids_t*)session->run_bulk(
+				session, (fsd_template_t*)jt,
+				start, end, incr
+				);
+	 }
+	EXCEPT_DEFAULT
+	 {
+		*job_ids = NULL;
+		fsd_exc_reraise();
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+
+static struct timespec *
+drmaa_timeout_time( signed long timeout, struct timespec *ts )
+{
+	if( timeout == DRMAA_TIMEOUT_WAIT_FOREVER )
+		return NULL;
+	else
+	 {
+		fsd_get_time( ts );
+		if( timeout != DRMAA_TIMEOUT_NO_WAIT )
+			ts->tv_sec += timeout;
+		return ts;
+	 }
+}
+
+
+int
+drmaa_synchronize(
+		const char **job_ids, signed long timeout,
+		int dispose,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+	struct timespec ts;
+
+	fsd_log_enter(( "(job_ids={...}, timeout=%ld, dispose=%d)",
+			timeout, dispose ));
+
+	if( job_ids == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		session->synchronize( session, job_ids,
+				drmaa_timeout_time(timeout, &ts), dispose );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_wait(
+		const char *job_id, char *job_id_out, size_t job_id_out_len,
+		int *stat, signed long timeout, drmaa_attr_values_t **rusage,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+	struct timespec ts;
+	char *result_job_id = NULL;
+
+	fsd_log_enter(( "(job_id=%s, timeout=%ld)", job_id, timeout ));
+
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		result_job_id = session->wait(
+				session, job_id, drmaa_timeout_time(timeout, &ts),
+				stat, (fsd_iter_t**)rusage
+				);
+		strlcpy( job_id_out, result_job_id, job_id_out_len );
+	 }
+	FINALLY
+	 {
+		fsd_free( result_job_id );
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =0: job_id=%s", job_id_out ));
+	DRMAA_API_END
+}
+
+
+#if 0
+int
+drmaa_get_contact(
+		char *contact, size_t contact_len,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	drmaa_session_t *volatile session = NULL;
+	const drmaa_implementation_info_t *impl_info = NULL;
+	const char *result = NULL;
+
+	impl_info = drmaa_get_implementation_info();
+	TRY
+	 {
+		session = drmaa_session_get();
+		if( session->contact )
+			result = session->contact;
+		else
+			result = impl_info->default_contact;
+		strlcpy( contact, result, contact_len );
+	 }
+	EXCEPT( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION )
+	 {
+		result = impl_info->default_contact;
+		strlcpy( contact, result, contact_len );
+	 }
+	FINALLY
+	 {
+		drmaa_session_release( session );
+	 }
+	END_TRY
+
+	DRMAA_API_END
+}
+#endif
+
+
+int
+drmaa_get_contact(
+		char *contact, size_t contact_len,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "" ));
+	strlcpy( contact, global->get_contact( global ), contact_len );
+	fsd_log_return(( " =0: %s", contact ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_version(
+		unsigned int *major, unsigned int *minor,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "" ));
+	global->get_version( global, major, minor );
+	fsd_log_return(( " =0: %d.%d", *major, *minor ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_DRM_system(
+		char *drm_system, size_t drm_system_len,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "" ));
+	strlcpy( drm_system, global->get_DRM_system( global ), drm_system_len );
+	fsd_log_return(( " =0: %s", drm_system ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_get_DRMAA_implementation(
+		char *drmaa_impl, size_t drmaa_impl_len,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_singletone_t *global = &_fsd_drmaa_singletone;
+	fsd_log_enter(( "" ));
+	strlcpy( drmaa_impl, global->get_DRMAA_implementation( global ), 
+			drmaa_impl_len );
+	fsd_log_return(( " =0: %s", drmaa_impl ));
+	DRMAA_API_END
+}
+
+
+const char *
+drmaa_strerror( int drmaa_errno )
+{
+	return fsd_drmaa_strerror( drmaa_errno );
+}
+
+
+int
+drmaa_read_configuration_file(
+		const char *filename, int must_exist,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	fsd_drmaa_session_t *volatile session = NULL;
+
+	DRMAA_API_BEGIN
+	fsd_log_enter(( "(filename=%s)", filename ));
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		session->read_configuration(
+				session, filename, must_exist, NULL, 0 );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+int
+drmaa_read_configuration(
+		const char *configuration, size_t configuration_len,
+		char *error_diagnosis, size_t error_diag_len
+		)
+{
+	DRMAA_API_BEGIN
+	fsd_drmaa_session_t *volatile session = NULL;
+	fsd_log_enter(( "(configuration=\"%.*s\")",
+				(int)configuration_len, configuration ));
+	TRY
+	 {
+		session = fsd_drmaa_session_get();
+		session->read_configuration(
+				session, NULL, false, configuration, configuration_len );
+	 }
+	FINALLY
+	 {
+		if( session )
+			session->release( session );
+	 }
+	END_TRY
+	fsd_log_return(( " =0" ));
+	DRMAA_API_END
+}
+
+
+
+fsd_drmaa_session_t *
+fsd_drmaa_session_get(void)
+{
+	fsd_drmaa_session_t *self = NULL;
+	fsd_mutex_lock( &_fsd_drmaa_singletone.session_mutex );
+	self = _fsd_drmaa_singletone.session;
+	fsd_mutex_unlock( &_fsd_drmaa_singletone.session_mutex );
+	if( self != NULL )
+	 {
+		fsd_mutex_lock( &self->mutex );
+		self->ref_cnt ++;
+		fsd_mutex_unlock( &self->mutex );
+	 }
+	else
+		fsd_exc_raise_code( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION );
+	return self;
+}
+
+
+#define wiffunc( name, args_decl, args_list ) \
+int drmaa_##name args_decl \
+{ \
+	return _fsd_drmaa_singletone.name args_list;\
+}
+
+wiffunc(
+		wifexited,
+		(	int *exited, int stat, char *error_diagnosis, size_t error_diag_len ),
+		( exited, stat, error_diagnosis, error_diag_len )
+		)
+
+wiffunc(
+		wexitstatus,
+		(	int *exit_status, int stat,
+			char *error_diagnosis, size_t error_diag_len ),
+		( exit_status, stat, error_diagnosis, error_diag_len )
+		)
+
+wiffunc(
+		wifsignaled,
+		(	int *signaled, int stat, char *error_diagnosis, size_t error_diag_len ),
+		( signaled, stat, error_diagnosis, error_diag_len )
+		)
+
+wiffunc(
+		wtermsig,
+		(	char *signal, size_t signal_len, int stat,
+			char *error_diagnosis, size_t error_diag_len ),
+		( signal, signal_len, stat, error_diagnosis, error_diag_len )
+		)
+
+wiffunc(
+		wcoredump,
+		(	int *core_dumped, int stat,
+			char *error_diagnosis, size_t error_diag_len ),
+		( core_dumped, stat, error_diagnosis, error_diag_len )
+		)
+
+wiffunc(
+		wifaborted,
+		(	int *aborted, int stat, char *error_diagnosis, size_t error_diag_len ),
+		( aborted, stat, error_diagnosis, error_diag_len )
+		)
+
+#endif
Index: /branches/2.0/drmaa2_utils/drmaa_utils/fsd_session.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/fsd_session.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/fsd_session.c	(revision 77)
@@ -0,0 +1,1033 @@
+/* $Id: fsd_session.c 28 2011-10-29 21:31:46Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <drmaa_utils/conf.h>
+#include <drmaa_utils/drmaa.h>
+#include <drmaa_utils/iter.h>
+#include <drmaa_utils/job.h>
+#include <drmaa_utils/session.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: fsd_session.c 28 2011-10-29 21:31:46Z mmamonski $";
+#endif
+
+
+static void
+fsd_drmaa_session_release( fsd_drmaa_session_t *self );
+
+static void
+fsd_drmaa_session_destroy(
+		fsd_drmaa_session_t *self );
+
+static void
+fsd_drmaa_session_destroy_nowait( fsd_drmaa_session_t *self );
+
+static char*
+fsd_drmaa_session_run_job(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt
+		);
+
+static fsd_iter_t*
+fsd_drmaa_session_run_bulk(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt,
+		int start, int end, int incr
+		);
+
+static void
+fsd_drmaa_session_control_job(
+		fsd_drmaa_session_t *self,
+		const char *job_id, int action
+		);
+
+static void
+fsd_drmaa_session_job_ps(
+		fsd_drmaa_session_t *self,
+		const char *job_id, int *remote_ps
+		);
+
+static void
+fsd_drmaa_session_synchronize(
+		fsd_drmaa_session_t *self,
+		const char **input_job_ids, const struct timespec *timeout,
+		bool dispose
+		);
+
+static char*
+fsd_drmaa_session_wait(
+		fsd_drmaa_session_t *self,
+		const char *job_id, const struct timespec *timeout,
+		int *status, fsd_iter_t **rusage
+		);
+
+static fsd_job_t *
+fsd_drmaa_session_new_job(
+		fsd_drmaa_session_t *self,
+		const char *job_id
+		);
+
+static char*
+fsd_drmaa_session_run_impl(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt, int bulk_incr
+		);
+
+static void
+fsd_drmaa_session_wait_for_single_job(
+		fsd_drmaa_session_t *self,
+		const char *job_id, const struct timespec *timeout,
+		int *status, fsd_iter_t **rusage, bool dispose
+		);
+
+static char*
+fsd_drmaa_session_wait_for_any_job(
+		fsd_drmaa_session_t *self,
+		const struct timespec *timeout,
+		int *status, fsd_iter_t **rusage,
+		bool dispose
+		);
+
+static void
+fsd_drmaa_session_wait_for_job_status_change(
+		fsd_drmaa_session_t *self,
+		fsd_cond_t *wait_condition,
+		fsd_mutex_t *mutex,
+		const struct timespec *timeout
+		);
+
+static void*
+fsd_drmaa_session_wait_thread( fsd_drmaa_session_t *self );
+
+static void
+fsd_drmaa_session_stop_wait_thread( fsd_drmaa_session_t *self );
+
+static void
+fsd_drmaa_session_update_all_jobs_status( fsd_drmaa_session_t *self );
+
+static char**
+fsd_drmaa_session_get_submited_job_ids(
+		fsd_drmaa_session_t *self
+		);
+
+static fsd_job_t*
+fsd_drmaa_session_get_job(
+		fsd_drmaa_session_t *self, const char *job_id
+		);
+
+static void
+fsd_drmaa_session_load_configuration(
+		fsd_drmaa_session_t *self, const char *basename
+		);
+
+static void
+fsd_drmaa_session_read_configuration(
+		fsd_drmaa_session_t *self,
+		const char *filename, bool must_exist,
+		const char *configuration, size_t config_len
+		);
+
+static void
+fsd_drmaa_session_apply_configuration(
+		fsd_drmaa_session_t *self
+		);
+
+
+
+fsd_drmaa_session_t *
+fsd_drmaa_session_new( const char *contact )
+{
+	fsd_drmaa_session_t *volatile self = NULL;
+
+	fsd_log_enter(( "(%s)", contact ));
+	TRY
+	 {
+		fsd_malloc( self, fsd_drmaa_session_t );
+
+		self->release = fsd_drmaa_session_release;
+		self->destroy = fsd_drmaa_session_destroy;
+		self->destroy_nowait = fsd_drmaa_session_destroy_nowait;
+		self->run_job = fsd_drmaa_session_run_job;
+		self->run_bulk = fsd_drmaa_session_run_bulk;
+		self->control_job = fsd_drmaa_session_control_job;
+		self->job_ps = fsd_drmaa_session_job_ps;
+		self->synchronize = fsd_drmaa_session_synchronize;
+		self->wait = fsd_drmaa_session_wait;
+		self->new_job = fsd_drmaa_session_new_job;
+		self->run_impl = fsd_drmaa_session_run_impl;
+		self->wait_for_single_job = fsd_drmaa_session_wait_for_single_job;
+		self->wait_for_any_job = fsd_drmaa_session_wait_for_any_job;
+		self->wait_for_job_status_change =
+			fsd_drmaa_session_wait_for_job_status_change;
+		self->wait_thread = fsd_drmaa_session_wait_thread;
+		self->stop_wait_thread = fsd_drmaa_session_stop_wait_thread;
+		self->update_all_jobs_status = fsd_drmaa_session_update_all_jobs_status;
+		self->get_submited_job_ids = fsd_drmaa_session_get_submited_job_ids;
+		self->get_job = fsd_drmaa_session_get_job;
+		self->load_configuration = fsd_drmaa_session_load_configuration;
+		self->read_configuration = fsd_drmaa_session_read_configuration;
+		self->apply_configuration = fsd_drmaa_session_apply_configuration;
+
+		self->ref_cnt = 1;
+		self->destroy_requested = false;
+		self->contact = NULL;
+		self->jobs = NULL;
+		self->configuration = NULL;
+		self->pool_delay.tv_sec = 10;
+		self->pool_delay.tv_nsec = 0;
+		self->cache_job_state = 0;
+		self->enable_wait_thread = false;
+		self->job_categories = NULL;
+		self->missing_jobs = FSD_REVEAL_MISSING_JOBS;
+		self->wait_thread_started = false;
+		self->wait_thread_run_flag = false;
+
+		fsd_mutex_init( &self->mutex );
+		fsd_cond_init( &self->wait_condition );
+		fsd_cond_init( &self->destroy_condition );
+		fsd_mutex_init( &self->drm_connection_mutex );
+		self->jobs = fsd_job_set_new();
+		self->contact = fsd_strdup( contact );
+		
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( self != NULL )
+			self->destroy( self );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+
+	return self;
+}
+
+
+void
+fsd_drmaa_session_release( fsd_drmaa_session_t *self )
+{
+	fsd_mutex_lock( &self->mutex );
+	self->ref_cnt--;
+	fsd_assert( self->ref_cnt > 0 );
+	if( self->ref_cnt == 1 )
+		fsd_cond_broadcast( &self->destroy_condition );
+	fsd_mutex_unlock( &self->mutex );
+}
+
+
+void
+fsd_drmaa_session_destroy( fsd_drmaa_session_t *self )
+{
+	bool already_destroying = false;
+
+	fsd_log_enter(( "" ));
+	fsd_mutex_lock( &self->mutex );
+	TRY
+	 {
+		if( self->destroy_requested )
+			already_destroying = true;
+		else
+		 {
+			self->destroy_requested = true;
+			fsd_cond_broadcast( &self->wait_condition );
+		 }
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &self->mutex ); }
+	END_TRY
+
+	if( already_destroying )
+	 { /* XXX: actually it can not happen in current implementation
+				when using DRMAA API */
+		self->release( self );
+		fsd_exc_raise_code( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION );
+	 }
+
+	self->jobs->signal_all( self->jobs );
+
+	fsd_mutex_lock( &self->mutex );
+	TRY
+	 {
+		while( self->ref_cnt > 1 )
+			fsd_cond_wait( &self->destroy_condition, &self->mutex );
+		fsd_log_debug(("started = %d  run_flag = %d", self->wait_thread_started, self->wait_thread_run_flag ));
+		if( self->wait_thread_started )
+			self->stop_wait_thread( self );
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &self->mutex ); }
+	END_TRY
+
+	self->destroy_nowait( self );
+	fsd_log_return(( "" ));
+}
+
+
+void
+fsd_drmaa_session_destroy_nowait( fsd_drmaa_session_t *self )
+{
+	fsd_log_enter(( "" ));
+	fsd_conf_dict_destroy( self->configuration );
+	fsd_free( self->contact );
+
+	if( self->jobs )
+		self->jobs->destroy( self->jobs );
+
+	fsd_mutex_destroy( &self->mutex );
+	fsd_cond_destroy( &self->wait_condition );
+	fsd_cond_destroy( &self->destroy_condition );
+	fsd_mutex_destroy( &self->drm_connection_mutex );
+
+	fsd_free( self );
+	fsd_log_return(( "" ));
+}
+
+
+char *
+fsd_drmaa_session_run_job(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt )
+{
+	return self->run_impl( self, jt, -1 );
+}
+
+
+fsd_iter_t *
+fsd_drmaa_session_run_bulk(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt,
+		int start, int end, int incr )
+{
+	volatile unsigned n_jobs;
+	char **volatile result = NULL;
+
+	if( incr > 0 )
+		n_jobs = (end-start) / incr + 1;
+	else
+		n_jobs = (start-end) / -incr + 1;
+
+	TRY
+	 {
+		unsigned i;
+		int idx;
+		fsd_calloc( result, n_jobs + 1, char* );
+		for( i=0, idx=start;  i < n_jobs;  i++, idx+=incr )
+			result[i] = self->run_impl( self, jt, idx );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( result )
+			fsd_free_vector( result );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+
+	return fsd_iter_new( result, -1 );
+}
+
+
+void
+fsd_drmaa_session_control_job(
+		fsd_drmaa_session_t *self,
+		const char *job_id, int action )
+{
+	char **job_ids = NULL;
+	char **i;
+
+	TRY
+	 {
+		if( !strcmp( job_id, DRMAA_JOB_IDS_SESSION_ALL ) )
+			job_ids = self->get_submited_job_ids( self );
+		else
+		 {
+			fsd_calloc( job_ids, 2, char* );
+			job_ids[0] = fsd_strdup( job_id );
+		 }
+
+		for( i = job_ids;  *i != NULL;  i++ )
+		 {
+			fsd_job_t *job = NULL;
+			TRY
+			 {
+				job = self->get_job( self, *i );
+				if( job == NULL )
+				 {
+					if( !strcmp( job_id, DRMAA_JOB_IDS_SESSION_ALL ) )
+					 { /* job was just removed from session */ }
+					else
+						job = self->new_job( self, *i );
+				 }
+				if( job )
+					job->control( job, action );
+			 }
+			FINALLY
+			 {
+				if ( job )
+				 job->release( job );
+			 }
+			END_TRY
+		 }
+	 }
+	FINALLY
+	 {
+		fsd_free_vector( job_ids );
+	 }
+	END_TRY
+}
+
+
+void
+fsd_drmaa_session_job_ps(
+		fsd_drmaa_session_t *self, const char *job_id, int *remote_ps )
+{
+	fsd_job_t *volatile job = NULL;
+	TRY
+	 {
+		job = self->get_job( self, job_id );
+		if( job == NULL )
+		 {
+			fsd_log_info(( "job_ps: recreating job object: %s", job_id ));
+			job = self->new_job( self, job_id );
+		 }
+		fsd_log_debug((" job->last_update_time = %u",  (unsigned int)job->last_update_time));
+		if( time(NULL) - job->last_update_time >= self->cache_job_state
+				|| job->state == DRMAA_PS_UNDETERMINED ) 
+		  {
+			fsd_log_debug(("updating status of job: %s ", job_id));
+			job->update_status( job );
+			job->last_update_time = time(NULL);
+		  }
+		*remote_ps = job->state;
+	 }
+	FINALLY
+	 {
+		if( job )
+			job->release( job );
+	 }
+	END_TRY
+}
+
+
+void
+fsd_drmaa_session_synchronize(
+		fsd_drmaa_session_t *self,
+		const char **input_job_ids, const struct timespec *timeout,
+		bool dispose
+		)
+{
+	volatile bool wait_for_all = false;
+	char **volatile job_ids_buf = NULL;
+	const char **job_ids = NULL;
+	const char **i;
+
+	fsd_log_enter(( "(job_ids={...}, timeout=..., dispose=%d)",
+			(int)dispose ));
+
+	if( input_job_ids == NULL )
+		fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+
+	TRY
+	 {
+		for( i = input_job_ids;  *i != NULL;  i++ )
+			if( !strcmp(*i, DRMAA_JOB_IDS_SESSION_ALL) )
+				wait_for_all = true;
+
+		if( wait_for_all )
+		 {
+			job_ids_buf = self->get_submited_job_ids( self );
+			job_ids = (const char**)job_ids_buf;
+		 }
+		else
+			job_ids = input_job_ids;
+
+		for( i = job_ids;  *i != NULL;  i++ )
+			TRY
+			 {
+				self->wait_for_single_job( self, *i, timeout, NULL, NULL, dispose );
+			 }
+			EXCEPT( FSD_DRMAA_ERRNO_INVALID_JOB )
+			 { /* job was ripped by another thread */ }
+			END_TRY
+	 }
+	FINALLY
+	 {
+		fsd_free_vector( job_ids_buf );
+	 }
+	END_TRY
+}
+
+
+char *
+fsd_drmaa_session_wait(
+		fsd_drmaa_session_t *self,
+		const char *job_id, const struct timespec *timeout,
+		int *stat, fsd_iter_t **rusage
+		)
+{
+	if( 0==strcmp(job_id, DRMAA_JOB_IDS_SESSION_ANY) )
+		return self->wait_for_any_job( self, timeout, stat, rusage, true );
+	else
+	 {
+		self->wait_for_single_job( self, job_id, timeout, stat, rusage, true );
+		return fsd_strdup( job_id );
+	 }
+}
+
+
+fsd_job_t *
+fsd_drmaa_session_new_job( fsd_drmaa_session_t *self, const char *job_id )
+{
+	fsd_job_t *job;
+	job = fsd_job_new( fsd_strdup(job_id) );
+	job->session = self;
+	return job;
+}
+
+
+char *
+fsd_drmaa_session_run_impl(
+		fsd_drmaa_session_t *self,
+		const fsd_template_t *jt, int bulk_incr )
+{
+	fsd_exc_raise_code( FSD_ERRNO_NOT_IMPLEMENTED );
+}
+
+
+void
+fsd_drmaa_session_wait_for_single_job(
+		fsd_drmaa_session_t *self,
+		const char *job_id, const struct timespec *timeout,
+		int *status, fsd_iter_t **rusage,
+		bool dispose
+		)
+{
+	fsd_job_t *volatile job = NULL;
+	volatile bool locked = false;
+
+	fsd_log_enter(( "(%s)", job_id ));
+	TRY
+	 {
+		job = self->get_job( self, job_id );
+		if( job == NULL )
+			fsd_exc_raise_fmt( FSD_DRMAA_ERRNO_INVALID_JOB,
+					"Job '%s' not found in DRMS queue", job_id );
+		job->update_status( job );
+		while( !self->destroy_requested  &&  job->state < DRMAA_PS_DONE )
+		 {
+			bool signaled = true;
+			fsd_log_debug(( "fsd_drmaa_session_wait_for_single_job: "
+						"waiting for %s to terminate", job_id ));
+			if( self->enable_wait_thread )
+			 {
+				if( timeout )
+					signaled = fsd_cond_timedwait(
+							&job->status_cond, &job->mutex, timeout );
+				else
+				 {
+					fsd_cond_wait( &job->status_cond, &job->mutex );
+				 }
+				if( !signaled )
+					fsd_exc_raise_code( FSD_DRMAA_ERRNO_EXIT_TIMEOUT );
+			 }
+			else
+			 {
+				self->wait_for_job_status_change(
+						self, &job->status_cond, &job->mutex, timeout );
+			 }
+
+			fsd_log_debug(( "fsd_drmaa_session_wait_for_single_job: woken up" ));
+			if( !self->enable_wait_thread )
+				job->update_status( job );
+		 }
+
+		if( self->destroy_requested )
+			fsd_exc_raise_code( FSD_DRMAA_ERRNO_EXIT_TIMEOUT );
+
+		job->get_termination_status( job, status, rusage );
+		if( dispose )
+		 {
+			job->release( job ); /*release mutex in order to ensure proper order of locking: first job_set mutex then job mutex */
+
+			locked = fsd_mutex_lock( &self->mutex );
+
+			job = self->get_job( self, job_id );
+			if (job != NULL)
+			 {
+				self->jobs->remove( self->jobs, job );
+				job->flags |= FSD_JOB_DISPOSED;
+			 }
+			else
+			 {
+				fsd_log_error(("Some other thread has already reaped job %s", job_id ));
+			 }
+
+			locked = fsd_mutex_unlock( &self->mutex );
+		 }
+	 }
+	FINALLY
+	 {
+		if ( job )
+			job->release( job );
+		if ( locked )
+			fsd_mutex_unlock( &self->mutex );
+	 }
+	END_TRY
+	fsd_log_return((""));
+}
+
+
+char *
+fsd_drmaa_session_wait_for_any_job(
+		fsd_drmaa_session_t *self,
+		const struct timespec *timeout,
+		int *status, fsd_iter_t **rusage,
+		bool dispose
+		)
+{
+	fsd_job_set_t *set = self->jobs;
+	fsd_job_t *volatile job = NULL;
+	char *volatile job_id = NULL;
+	volatile bool locked = false;
+
+	fsd_log_enter(( "" ));
+
+	TRY
+	 {
+		while( job == NULL )
+		 {
+			bool signaled = true;
+
+			if( self->destroy_requested )
+				fsd_exc_raise_code( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION );
+
+			if( !self->enable_wait_thread )
+				self->update_all_jobs_status( self );
+
+			locked = fsd_mutex_lock( &self->mutex );
+			if( set->empty( set ) )
+				fsd_exc_raise_msg( FSD_DRMAA_ERRNO_INVALID_JOB,
+						"No job found to be waited for" );
+
+			if( (job = set->find_terminated( set )) != NULL )
+				break;
+
+			if( self->destroy_requested )
+				fsd_exc_raise_code( FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION );
+			if( self->enable_wait_thread )
+			 {
+				fsd_log_debug(( "wait_for_any_job: waiting for wait thread" ));
+				if( timeout )
+					signaled = fsd_cond_timedwait(
+							&self->wait_condition, &self->mutex, timeout );
+				else
+					fsd_cond_wait( &self->wait_condition, &self->mutex );
+			 }
+			else
+			 {
+				fsd_log_debug(( "wait_for_any_job: waiting for next check" ));
+				self->wait_for_job_status_change( self,
+						&self->wait_condition, &self->mutex, timeout );
+			 }
+			locked = fsd_mutex_unlock( &self->mutex );
+			fsd_log_debug((
+						"wait_for_any_job: woken up; signaled=%d", signaled ));
+
+			if( !signaled )
+				fsd_exc_raise_code( FSD_DRMAA_ERRNO_EXIT_TIMEOUT );
+
+		 }
+		fsd_log_debug(( "wait_for_any_job: waiting finished" ));
+
+		job_id = fsd_strdup( job->job_id );
+		job->get_termination_status( job, status, rusage );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( job_id )
+			fsd_free( job_id );
+		fsd_exc_reraise();
+	 }
+	FINALLY
+	 {
+		if( job )
+		 {
+			if( fsd_exc_get() == NULL  &&  dispose )
+			 {
+				set->remove( set, job );
+				job->flags |= FSD_JOB_DISPOSED;
+			 }
+			job->release( job );
+		 }
+		if( locked )
+			fsd_mutex_unlock( &self->mutex );
+	 }
+	END_TRY
+
+	fsd_log_return(( " =%s", job_id ));
+	return job_id;
+}
+
+
+void
+fsd_drmaa_session_wait_for_job_status_change(
+		fsd_drmaa_session_t *self,
+		fsd_cond_t *wait_condition,
+		fsd_mutex_t *mutex,
+		const struct timespec *timeout
+		)
+{
+	struct timespec ts, *next_check = &ts;
+	bool status_changed;
+
+	if( timeout )
+		fsd_log_enter((
+					"(timeout=%ld.%09ld)",
+					timeout->tv_sec, timeout->tv_nsec ));
+	else
+		fsd_log_enter(( "(timeout=(null))" ));
+	fsd_get_time( next_check );
+	fsd_ts_add( next_check, &self->pool_delay );
+	if( timeout  &&  fsd_ts_cmp( timeout, next_check ) < 0 )
+		next_check = (struct timespec*)timeout;
+	fsd_log_debug(( "wait_for_job_status_change: waiting untill %ld.%09ld",
+				next_check->tv_sec, next_check->tv_nsec ));
+	status_changed = fsd_cond_timedwait(wait_condition, mutex,(const struct timespec *) next_check );
+	if( !status_changed  &&  next_check == timeout )
+		fsd_exc_raise_code( FSD_DRMAA_ERRNO_EXIT_TIMEOUT );
+
+	fsd_log_return(( ": next_check=%ld.%09ld, status_changed=%d",
+				next_check->tv_sec, next_check->tv_nsec,
+				(int)status_changed
+				));
+}
+
+
+void *
+fsd_drmaa_session_wait_thread( fsd_drmaa_session_t *self )
+{
+	struct timespec ts, *next_check = &ts;
+	bool volatile locked = false;
+
+	fsd_log_enter(( "" ));
+	locked = fsd_mutex_lock( &self->mutex );
+	TRY
+	 {
+		while( self->wait_thread_run_flag )
+			TRY
+			 {
+				fsd_log_debug(( "wait thread: next iteration" ));
+				self->update_all_jobs_status( self );
+				fsd_cond_broadcast( &self->wait_condition );
+				
+				fsd_get_time( next_check );
+				fsd_ts_add( next_check, &self->pool_delay );
+				fsd_cond_timedwait( &self->wait_condition, &self->mutex, (const struct timespec *) next_check );
+				
+			 }
+			EXCEPT_DEFAULT
+			 {
+				const fsd_exc_t *e = fsd_exc_get();
+				fsd_log_error(( "wait thread: <%d:%s>", e->code(e), e->message(e) ));
+			 }
+			END_TRY
+	 }
+	FINALLY
+	 { 
+		if (locked)
+			fsd_mutex_unlock( &self->mutex ); 
+	 }
+	END_TRY
+
+	fsd_log_return(( " =NULL" ));
+	return NULL;
+}
+
+
+void
+fsd_drmaa_session_stop_wait_thread( fsd_drmaa_session_t *self )
+{
+	volatile int lock_count = 0;
+	fsd_log_enter(( "" ));
+	fsd_mutex_lock( &self->mutex );
+	TRY
+	 {
+		fsd_log_debug(("started = %d  run_flag = %d", self->wait_thread_started, self->wait_thread_run_flag ));
+		if( self->wait_thread_started )
+		 {
+			self->wait_thread_run_flag = false;
+			fsd_log_debug(("started = %d  run_flag = %d", self->wait_thread_started, self->wait_thread_run_flag ));
+			fsd_cond_broadcast( &self->wait_condition );
+			TRY
+			 {
+				lock_count = fsd_mutex_unlock_times( &self->mutex );
+				fsd_thread_join( self->wait_thread_handle, NULL );
+			 }
+			FINALLY
+			 {
+				int i;
+				for( i = 0;  i < lock_count;  i++ )
+					fsd_mutex_lock( &self->mutex );
+			 }
+			END_TRY
+			self->wait_thread_started = false;
+		 }
+
+	 }
+	FINALLY
+	 { fsd_mutex_unlock( &self->mutex ); }
+	END_TRY
+	fsd_log_return(( "" ));
+}
+
+
+void
+fsd_drmaa_session_update_all_jobs_status(
+		fsd_drmaa_session_t *self )
+{
+	char **volatile job_ids = NULL;
+	fsd_log_enter(( "" ));
+	TRY
+	 {
+		const char **i;
+		fsd_job_t *volatile job = NULL;
+		job_ids = self->get_submited_job_ids( self );
+		for( i = (const char **)job_ids;  *i;  i++ )
+			TRY
+			 {
+				job = self->get_job( self, *i );
+				if( job )
+					job->update_status( job );
+			 }
+			FINALLY
+			 {
+				if( job )
+					job->release( job );
+			 }
+			END_TRY
+	 }
+	FINALLY
+	 {
+		fsd_free_vector( job_ids );
+	 }
+	END_TRY
+	fsd_log_return(( "" ));
+}
+
+
+char **
+fsd_drmaa_session_get_submited_job_ids( fsd_drmaa_session_t *self )
+{
+	return self->jobs->get_all_job_ids( self->jobs );
+}
+
+
+fsd_job_t *
+fsd_drmaa_session_get_job( fsd_drmaa_session_t *self, const char *job_id )
+{
+	return self->jobs->get( self->jobs, job_id );
+}
+
+
+void
+fsd_drmaa_session_load_configuration(
+		fsd_drmaa_session_t *self, const char *basename
+		)
+{
+	char *volatile system_conf = NULL;
+	char *volatile user_conf = NULL;
+	char *volatile varname = NULL;
+	TRY
+	 {
+		const char *home;
+		const char *envvalue;
+		char *i;
+
+		system_conf = fsd_asprintf( DRMAA_DIR_SYSCONF"/%s.conf", basename );
+
+		home = getenv( "HOME" );
+		if( home == NULL )
+		 { home = "."; }
+		user_conf = fsd_asprintf( "%s/.%s.conf", home, basename );
+
+		varname = fsd_asprintf( "%s_CONF", basename );
+		for( i = varname;  *i;  i++ )
+			*i = toupper( *(unsigned char*)i );
+		envvalue = getenv( varname );
+
+		self->configuration = fsd_conf_read(
+			 self->configuration, system_conf, false, NULL, 0 );
+		self->configuration = fsd_conf_read(
+			 self->configuration, user_conf, false, NULL, 0 );
+		if( envvalue )
+			self->configuration = fsd_conf_read(
+				 self->configuration, envvalue, true, NULL, 0 );
+		self->apply_configuration( self );
+	 }
+	FINALLY
+	 {
+		fsd_free( system_conf );
+		fsd_free( user_conf );
+		fsd_free( varname );
+	 }
+	END_TRY
+}
+
+
+void
+fsd_drmaa_session_read_configuration(
+		fsd_drmaa_session_t *self,
+		const char *filename, bool must_exist,
+		const char *configuration, size_t configuration_len
+		)
+{
+	self->configuration = fsd_conf_read(
+		 self->configuration,
+		 filename, must_exist,
+		 configuration, configuration_len );
+	self->apply_configuration( self );
+}
+
+
+void
+fsd_drmaa_session_apply_configuration( fsd_drmaa_session_t *self )
+{
+	fsd_conf_option_t *pool_delay = NULL;
+	fsd_conf_option_t *cache_job_state = NULL;
+	fsd_conf_option_t *wait_thread = NULL;
+	fsd_conf_option_t *job_categories = NULL;
+	fsd_conf_option_t *missing_jobs = NULL;
+
+	fsd_log_enter((""));
+	if( self->configuration  !=  NULL ) {
+
+		pool_delay = fsd_conf_dict_get(
+				self->configuration, "pool_delay" );
+		cache_job_state = fsd_conf_dict_get(
+				self->configuration, "cache_job_state" );
+		wait_thread = fsd_conf_dict_get(
+				self->configuration, "wait_thread" );
+		job_categories = fsd_conf_dict_get(
+				self->configuration, "job_categories" );
+		missing_jobs = fsd_conf_dict_get(
+				self->configuration, "missing_jobs" );
+	}
+
+	if( pool_delay )
+	 {
+		if( pool_delay->type == FSD_CONF_INTEGER
+				&&  pool_delay->val.integer > 0 )
+		 {
+			fsd_log_debug(("pool_delay=%d", pool_delay->val.integer));
+			self->pool_delay.tv_sec = pool_delay->val.integer;
+		 }
+		else
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"configuration: 'pool_delay' must be positive integer"
+					);
+	 }
+	if( cache_job_state )
+	 {
+		if( cache_job_state->type == FSD_CONF_INTEGER
+				&&   cache_job_state->val.integer >= 0 )
+		 {
+			fsd_log_debug(("cache_job_state=%d", cache_job_state->val.integer));
+			self->cache_job_state = cache_job_state->val.integer;
+		 }
+		else
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"configuration: 'cache_job_state' must be nonnegative integer"
+					);
+	 }
+	if( wait_thread )
+	 {
+		if( wait_thread->type == FSD_CONF_INTEGER )
+		 {
+
+			fsd_log_info(("wait_thread=%d", wait_thread->val.integer));
+			self->enable_wait_thread = (wait_thread->val.integer != 0 );
+		 }
+		else
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"configuration: 'wait_thread' should be 0 or 1"
+					);
+	 }
+	if( job_categories )
+	 {
+		if( job_categories->type == FSD_CONF_DICT )
+			self->job_categories = job_categories->val.dict;
+		else
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"configuration: 'job_categories' should be dictionary"
+					);
+	 }
+	if( missing_jobs )
+	 {
+		bool ok = true;
+		if( missing_jobs->type != FSD_CONF_STRING )
+		 {
+			const char *value = missing_jobs->val.string;
+			if( !strcmp( value, "ignore" ) )
+				self->missing_jobs = FSD_IGNORE_MISSING_JOBS;
+			else if( !strcmp( value, "ignore-queued" ) )
+				self->missing_jobs = FSD_IGNORE_QUEUED_MISSING_JOBS;
+			else if( !strcmp( value, "reveal" ) )
+				self->missing_jobs = FSD_REVEAL_MISSING_JOBS;
+			else
+				ok = false;
+		 }
+		else
+			ok = false;
+
+		if( !ok )
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"configuration: 'missing_jobs' should be one of: "
+					"'ignore', 'ignore-queued' or 'reveal'"
+					);
+	 }
+
+	if( self->enable_wait_thread  &&  !self->wait_thread_started )
+	 {
+		fsd_log_debug(("Starting wait thread"));
+		self->wait_thread_run_flag = true;
+		fsd_thread_create( &self->wait_thread_handle,
+				(void*(*)(void*))self->wait_thread, self );
+		self->wait_thread_started = true;
+		fsd_log_debug(( "wait thread started" ));
+	 }
+	else if( !self->enable_wait_thread  &&  self->wait_thread_started )
+	 {
+		fsd_log_debug(("Stopping wait thread"));
+		self->stop_wait_thread( self );
+	 }
+
+	fsd_log_return((""));
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/environ.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/environ.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/environ.c	(revision 77)
@@ -0,0 +1,241 @@
+/* $Id: environ.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/environ.h>
+#include <drmaa_utils/lookup3.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: environ.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+static void
+fsd_environ_destroy( fsd_environ_t *self )
+{
+	unsigned i;
+	fsd_environ_item_t *j;
+	if( self->_table )
+	 {
+		for( i = 0;  i < self->_table_size;  i++ )
+			for( j = self->_table[i];  j != NULL; )
+			 {
+				fsd_environ_item_t *to_delete = j;
+				j = j->next;
+				fsd_free( to_delete->name );
+				fsd_free( to_delete->value );
+				fsd_free( to_delete );
+			 }
+		fsd_free( self->_table );
+	 }
+	fsd_free( self );
+}
+
+static const char *
+fsd_environ_get( fsd_environ_t *self, const char *name )
+{
+	uint32_t hash;
+	const fsd_environ_item_t *i;
+	hash = hashstr( name, strlen(name), 0 );
+	hash &= self->_table_size - 1;
+	for( i = self->_table[hash];  i != NULL;  i = i->next )
+		if( strcmp( i->name, name ) == 0 )
+			return i->value;
+	return NULL;
+}
+
+static void
+fsd_environ_set( fsd_environ_t *self, char *name, char *value )
+{
+	uint32_t hash;
+	fsd_environ_item_t *i;
+	fsd_environ_item_t *item = NULL;
+	bool replaced = false;
+
+	TRY
+	 {
+		hash = hashstr( name, strlen(name), 0 );
+		hash &= self->_table_size - 1;
+		for( i = self->_table[hash];  i != NULL;  i = i->next )
+		 {
+			if( strcmp( i->name, name ) == 0 )
+			 {
+				fsd_free( i->value );
+				i->value = value;
+				replaced = true;
+				break;
+			 }
+		 }
+
+		if( !replaced )
+		 {
+			fsd_malloc( item, fsd_environ_item_t );
+			item->next = self->_table[hash];
+			item->name = name;
+			item->value = value;
+			self->_table[hash] = item;
+		 }
+	 }
+	EXCEPT_DEFAULT
+	 {
+		fsd_free( name );
+		fsd_free( value );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+}
+
+static void
+fsd_environ_update( fsd_environ_t *self, const char *const envp[] )
+{
+	const char *const *i;
+	for( i = envp;  *i;  i++ )
+	 {
+		const char *eq;
+		char *volatile name = NULL;
+		char *volatile value = NULL;
+		eq = strchr( *i, '=' );
+		if( eq == NULL )
+			fsd_exc_raise_code( FSD_ERRNO_INVALID_VALUE_FORMAT );
+		name = fsd_strndup( *i, eq-*i );
+		TRY
+		 { value = fsd_strdup( eq+1 ); }
+		EXCEPT_DEFAULT
+		 { fsd_free(name); fsd_exc_reraise(); }
+		END_TRY
+		self->set( self, name, value );
+	 }
+}
+
+static char **
+fsd_environ_list( fsd_environ_t *self )
+{
+	uint32_t i;
+	const fsd_environ_item_t *j;
+	char **volatile result = NULL;
+	unsigned items = 0;
+
+	TRY
+	 {
+		for( i = 0;  i < self->_table_size;  i++ )
+			for( j = self->_table[i];  j != NULL;  j = j->next )
+			 {
+				items++;
+				fsd_realloc( result, items+1, char* );
+				result[items] = NULL;
+				result[items-1] = fsd_asprintf( "%s=%s", j->name, j->value );
+			 }
+	 }
+	EXCEPT_DEFAULT
+	 {
+		fsd_free_vector( result );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+
+	i = 0;
+	while (result[i])
+	 {
+		fsd_log_debug(("enc[%d]=%s",i, result[i]));
+		i++;
+	 }
+
+	return result;
+}
+
+static fsd_environ_t *
+fsd_environ_apply( fsd_environ_t *self )
+{
+	uint32_t i;
+	const fsd_environ_item_t *j;
+	fsd_environ_t *volatile saved_state =NULL;
+	TRY
+	 {
+		saved_state = fsd_environ_new( NULL );
+		for( i = 0;  i < self->_table_size;  i++ )
+			for( j = self->_table[i];  j != NULL;  j = j->next )
+			 {
+				const char *value = getenv( j->name );
+				if( value )
+					saved_state->set( saved_state,
+							fsd_strdup(j->name), fsd_strdup(value) );
+				setenv( j->name, j->value, 1 );
+			 }
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( saved_state )
+			saved_state->destroy( saved_state );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+	return saved_state;
+}
+
+static void
+fsd_environ_restore( fsd_environ_t *self, fsd_environ_t *saved_state )
+{
+	uint32_t i;
+	const fsd_environ_item_t *j;
+	for( i = 0;  i < self->_table_size;  i++ )
+		for( j = self->_table[i];  j != NULL;  j = j->next )
+		 {
+			const char *value = saved_state->get( saved_state, j->name );
+			if( value )
+				setenv( j->name, value, 1 );
+			else
+				unsetenv( j->name );
+		 }
+}
+
+fsd_environ_t *
+fsd_environ_new( const char *const envp[] )
+{
+	fsd_environ_t *volatile self = NULL;
+	TRY
+	 {
+		fsd_malloc( self, fsd_environ_t );
+		self->destroy = fsd_environ_destroy;
+		self->get = fsd_environ_get;
+		self->set = fsd_environ_set;
+		self->update = fsd_environ_update;
+		self->list = fsd_environ_list;
+		self->apply = fsd_environ_apply;
+		self->restore = fsd_environ_restore;
+		self->_table_size = 256;
+		fsd_calloc( self->_table, self->_table_size, fsd_environ_item_t* );
+		if( envp )
+			self->update( self, envp );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( self )
+			self->destroy( self );
+	 }
+	END_TRY
+	return self;
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.h	(revision 77)
@@ -0,0 +1,88 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INTEGER = 258,
+     STRING = 259,
+     LEXER_ERROR = 260
+   };
+#endif
+/* Tokens.  */
+#define INTEGER 258
+#define STRING 259
+#define LEXER_ERROR 260
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 36 "conf_tab.y"
+{
+	int integer;
+	char *string;
+	fsd_conf_option_t *option;
+	fsd_conf_dict_t *dictionary;
+	fsd_conf_pair_t pair;
+}
+/* Line 1529 of yacc.c.  */
+#line 67 "conf_tab.h"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.c	(revision 77)
@@ -0,0 +1,431 @@
+/* $Id: drmaa_util.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/drmaa_attrib.h>
+#include <drmaa_utils/drmaa_util.h>
+#include <drmaa_utils/logging.h>
+#include <drmaa_utils/template.h>
+#include <drmaa_utils/util.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: drmaa_util.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+static char *
+fsd_expand_drmaa_ph_expand( fsd_expand_drmaa_ph_t *self, char *s, unsigned set )
+{
+	unsigned mask;
+
+	for(
+			mask = 1;
+			mask <= FSD_DRMAA_PH_INCR;
+			mask <<= 1
+			)
+	 {
+		const char *ph;
+		const char *value;
+
+		switch( mask )
+		 {
+			case FSD_DRMAA_PH_HD:
+				ph = DRMAA_PLACEHOLDER_HD;
+				value = self->home_directory;
+				break;
+			case FSD_DRMAA_PH_WD:
+				ph = DRMAA_PLACEHOLDER_WD;
+				value = self->working_directory;
+				break;
+			case FSD_DRMAA_PH_INCR:
+				ph = DRMAA_PLACEHOLDER_INCR;
+				value = self->bulk_incr;
+				break;
+			default:
+				fsd_assert( false );
+		 }
+		if( value == NULL )
+			value = "";
+
+		if( mask & set )
+			s = fsd_replace( s, ph, value );
+		else if( strstr( s, ph ) != NULL )
+		 {
+			fsd_log_warning((
+						"'%s' can not be expanded in '%s'; removing from string",
+						ph, s ));
+			s = fsd_replace( s, ph, "" );
+		 }
+	 }
+
+	return s;
+}
+
+static void
+fsd_expand_drmaa_ph_set( fsd_expand_drmaa_ph_t *self,
+		int placeholder, char *value )
+{
+	char **var;
+	switch( placeholder )
+	 {
+		case FSD_DRMAA_PH_HD:  var = &self->home_directory;  break;
+		case FSD_DRMAA_PH_WD:  var = &self->working_directory;  break;
+		case FSD_DRMAA_PH_INCR:  var = &self->bulk_incr;  break;
+		default:
+			fsd_free( value );
+			fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT );
+	 }
+	fsd_free( *var );
+	*var = value;
+}
+
+static void
+fsd_expand_drmaa_ph_destroy( fsd_expand_drmaa_ph_t *self )
+{
+	if( self != NULL )
+	 {
+		fsd_free( self->home_directory );
+		fsd_free( self->working_directory );
+		fsd_free( self->bulk_incr );
+		fsd_free( self );
+	 }
+}
+
+fsd_expand_drmaa_ph_t *
+fsd_expand_drmaa_ph_new(
+		char *home_directory,
+		char *working_directory,
+		char *bulk_incr
+		)
+{
+	fsd_expand_drmaa_ph_t *volatile p = NULL;
+
+	TRY
+	 {
+		fsd_expand_drmaa_ph_t *self;
+		fsd_malloc( p, fsd_expand_drmaa_ph_t );
+		self = p;
+		self->expand = fsd_expand_drmaa_ph_expand;
+		self->set = fsd_expand_drmaa_ph_set;
+		self->destroy = fsd_expand_drmaa_ph_destroy;
+
+		self->home_directory = home_directory;
+		self->working_directory = working_directory;
+		self->bulk_incr = bulk_incr;
+
+		if( self->home_directory == NULL )
+		 {
+			const char *home = getenv("HOME");
+			if( home == NULL )
+				home = "";
+			self->home_directory = fsd_strdup( home );
+		 }
+
+		if( self->working_directory == NULL )
+			self->working_directory = fsd_strdup(
+					self->home_directory );
+		else
+			self->working_directory = self->expand( self,
+					self->working_directory, FSD_DRMAA_PH_HD );
+
+		if( self->bulk_incr == NULL )
+			self->bulk_incr = fsd_strdup( "" );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( p )
+			p->destroy( p );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+	return p;
+}
+
+
+const char *
+drmaa_control_to_str( int action )
+{
+	switch( action )
+	 {
+		case DRMAA_CONTROL_SUSPEND:
+			return "suspend";
+		case DRMAA_CONTROL_RESUME:
+			return "resume";
+		case DRMAA_CONTROL_HOLD:
+			return "hold";
+		case DRMAA_CONTROL_RELEASE:
+			return "release";
+		case DRMAA_CONTROL_TERMINATE:
+			return "terminate";
+		default:
+			return "?";
+	 }
+}
+
+
+const char *
+drmaa_job_ps_to_str( int ps )
+{
+	switch( ps )
+	 {
+		case DRMAA_PS_UNDETERMINED:
+			return "undetermined";
+		case DRMAA_PS_QUEUED_ACTIVE:
+			return "queued_active";
+		case DRMAA_PS_SYSTEM_ON_HOLD:
+			return "system_on_hold";
+		case DRMAA_PS_USER_ON_HOLD:
+			return "user_on_hold";
+		case DRMAA_PS_USER_SYSTEM_ON_HOLD:
+			return "user_system_on_hold";
+		case DRMAA_PS_RUNNING:
+			return "running";
+		case DRMAA_PS_SYSTEM_SUSPENDED:
+			return "system_suspended";
+		case DRMAA_PS_USER_SUSPENDED:
+			return "user_suspended";
+		case DRMAA_PS_USER_SYSTEM_SUSPENDED:
+			return "user_system_suspended";
+		case DRMAA_PS_DONE:
+			return "done";
+		case DRMAA_PS_FAILED:
+			return "failed";
+		default:
+			return "?";
+	 }
+}
+
+
+int
+fsd_drmaa_code( int fsd_errno )
+{
+	switch( fsd_errno )
+	 {
+		case FSD_ERRNO_SUCCESS:
+			return DRMAA_ERRNO_SUCCESS;
+		case FSD_ERRNO_INTERNAL_ERROR:
+			return DRMAA_ERRNO_INTERNAL_ERROR;
+		case FSD_ERRNO_NO_MEMORY:
+			return DRMAA_ERRNO_NO_MEMORY;
+		case FSD_ERRNO_INVALID_ARGUMENT:
+			return DRMAA_ERRNO_INVALID_ARGUMENT;
+		case FSD_ERRNO_INVALID_VALUE:
+			return DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE;
+		case FSD_ERRNO_INVALID_VALUE_FORMAT:
+			return DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT;
+		case FSD_ERRNO_STOP_ITERATION:
+			return DRMAA_ERRNO_NO_MORE_ELEMENTS;
+		case FSD_ERRNO_NOT_IMPLEMENTED:
+			return DRMAA_ERRNO_INTERNAL_ERROR;
+		case FSD_ERRNO_NOT_INITIALIZED:
+			return DRMAA_ERRNO_NO_ACTIVE_SESSION;
+		case FSD_ERRNO_TIMEOUT:
+			return DRMAA_ERRNO_EXIT_TIMEOUT;
+		case FSD_ERRNO_AUTH_FAILURE:
+			return DRMAA_ERRNO_AUTH_FAILURE;
+		case FSD_ERRNO_AUTHZ_FAILURE:
+			return DRMAA_ERRNO_AUTH_FAILURE;
+		case FSD_ERRNO_TRY_LATER:
+			return DRMAA_ERRNO_TRY_LATER;
+		case FSD_ERRNO_DRM_COMMUNICATION_FAILURE:
+			return DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE;
+		case FSD_ERRNO_DRMS_INIT_FAILED:
+			return DRMAA_ERRNO_DRMS_INIT_FAILED;
+		case FSD_ERRNO_DRMS_EXIT_ERROR:
+			return DRMAA_ERRNO_DRMS_EXIT_ERROR;
+		case FSD_ERRNO_DENIED_BY_DRM:
+			return DRMAA_ERRNO_DENIED_BY_DRM;
+
+		case FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION:
+			return DRMAA_ERRNO_NO_ACTIVE_SESSION;
+		case FSD_DRMAA_ERRNO_INVALID_CONTACT_STRING:
+			return DRMAA_ERRNO_INVALID_CONTACT_STRING;
+		case FSD_DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR:
+			return DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR;
+		case FSD_DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED:
+			return DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED;
+		case FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION:
+			return DRMAA_ERRNO_ALREADY_ACTIVE_SESSION;
+		case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT:
+			return DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT;
+		case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE:
+			return DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE;
+		case FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES:
+			return DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES;
+		case FSD_DRMAA_ERRNO_INVALID_JOB:
+			return DRMAA_ERRNO_INVALID_JOB;
+		case FSD_DRMAA_ERRNO_RESUME_INCONSISTENT_STATE:
+			return DRMAA_ERRNO_RESUME_INCONSISTENT_STATE;
+		case FSD_DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE:
+			return DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE;
+		case FSD_DRMAA_ERRNO_HOLD_INCONSISTENT_STATE:
+			return DRMAA_ERRNO_HOLD_INCONSISTENT_STATE;
+		case FSD_DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE:
+			return DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE;
+		case FSD_DRMAA_ERRNO_EXIT_TIMEOUT:
+			return DRMAA_ERRNO_EXIT_TIMEOUT;
+		case FSD_DRMAA_ERRNO_NO_RUSAGE:
+			return DRMAA_ERRNO_NO_RUSAGE;
+
+		default:
+			return DRMAA_ERRNO_INTERNAL_ERROR;
+	 }
+}
+
+
+int
+fsd_errno_from_drmaa_code( int drmaa_errno )
+{
+	switch( drmaa_errno )
+	 {
+		case DRMAA_ERRNO_SUCCESS:
+			return FSD_ERRNO_SUCCESS;
+		case DRMAA_ERRNO_INTERNAL_ERROR:
+			return FSD_ERRNO_INTERNAL_ERROR;
+		case DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE:
+			return FSD_ERRNO_DRM_COMMUNICATION_FAILURE;
+		case DRMAA_ERRNO_AUTH_FAILURE:
+			return FSD_ERRNO_AUTHZ_FAILURE;
+		case DRMAA_ERRNO_INVALID_ARGUMENT:
+			return FSD_ERRNO_INVALID_ARGUMENT;
+		case DRMAA_ERRNO_NO_ACTIVE_SESSION:
+			return FSD_ERRNO_NOT_INITIALIZED;
+		case DRMAA_ERRNO_NO_MEMORY:
+			return FSD_ERRNO_NO_MEMORY;
+		case DRMAA_ERRNO_INVALID_CONTACT_STRING:
+			return FSD_DRMAA_ERRNO_INVALID_CONTACT_STRING;
+		case DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR:
+			return FSD_DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR;
+		case DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED:
+			return FSD_DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED;
+		case DRMAA_ERRNO_DRMS_INIT_FAILED:
+			return FSD_ERRNO_DRMS_INIT_FAILED;
+		case DRMAA_ERRNO_ALREADY_ACTIVE_SESSION:
+			return FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION;
+		case DRMAA_ERRNO_DRMS_EXIT_ERROR:
+			return FSD_ERRNO_DRMS_EXIT_ERROR;
+		case DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT:
+			return FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT;
+		case DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE:
+			return FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE;
+		case DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES:
+			return FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES;
+		case DRMAA_ERRNO_TRY_LATER:
+			return FSD_ERRNO_TRY_LATER;
+		case DRMAA_ERRNO_DENIED_BY_DRM:
+			return FSD_ERRNO_DENIED_BY_DRM;
+		case DRMAA_ERRNO_INVALID_JOB:
+			return FSD_DRMAA_ERRNO_INVALID_JOB;
+		case DRMAA_ERRNO_RESUME_INCONSISTENT_STATE:
+			return FSD_DRMAA_ERRNO_RESUME_INCONSISTENT_STATE;
+		case DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE:
+			return FSD_DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE;
+		case DRMAA_ERRNO_HOLD_INCONSISTENT_STATE:
+			return FSD_DRMAA_ERRNO_HOLD_INCONSISTENT_STATE;
+		case DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE:
+			return FSD_DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE;
+		case DRMAA_ERRNO_EXIT_TIMEOUT:
+			return FSD_DRMAA_ERRNO_EXIT_TIMEOUT;
+		case DRMAA_ERRNO_NO_RUSAGE:
+			return FSD_DRMAA_ERRNO_NO_RUSAGE;
+		case DRMAA_ERRNO_NO_MORE_ELEMENTS:
+			return FSD_ERRNO_STOP_ITERATION;
+		default:
+			fsd_assert(false);
+			return FSD_ERRNO_INTERNAL_ERROR;
+	 }
+}
+
+
+const char *
+fsd_drmaa_strerror( int drmaa_errno )
+{
+	switch( drmaa_errno )
+	 {
+		case DRMAA_ERRNO_SUCCESS:
+			return "Success.";
+		case DRMAA_ERRNO_INTERNAL_ERROR:
+			return "Unexpected or internal DRMAA error.";
+		case DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE:
+			return "Could not contact DRM system for this request.";
+		case DRMAA_ERRNO_AUTH_FAILURE:
+			return "Authorization failure.";
+		case DRMAA_ERRNO_INVALID_ARGUMENT:
+			return "Invalid argument value.";
+		case DRMAA_ERRNO_NO_ACTIVE_SESSION:
+			return "No active DRMAA session.";
+		case DRMAA_ERRNO_NO_MEMORY:
+			return "Not enough memory.";
+		case DRMAA_ERRNO_INVALID_CONTACT_STRING:
+			return "Invalid contact string.";
+		case DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR:
+			return "Can not determine default contact to DRM system.";
+		case DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED:
+			return "Contact to DRM must be set explicitly "
+				"because there is no default.";
+		case DRMAA_ERRNO_DRMS_INIT_FAILED:
+			return "Unable to initialize DRM system.";
+		case DRMAA_ERRNO_ALREADY_ACTIVE_SESSION:
+			return "DRMAA session already exist.";
+		case DRMAA_ERRNO_DRMS_EXIT_ERROR:
+			return "Disengagement from the DRM system failed.";
+		case DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT:
+			return "Invalid format of job attribute.";
+		case DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE:
+			return "Invalid value of job attribute.";
+		case DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES:
+			return "Value of attribute conflicts with other attribute value.";
+		case DRMAA_ERRNO_TRY_LATER:
+			return "DRM system is overloaded.  Try again later.";
+		case DRMAA_ERRNO_DENIED_BY_DRM:
+			return "DRM rejected job due to its configuration or job attributes.";
+		case DRMAA_ERRNO_INVALID_JOB:
+			return "Job does not exist in DRMs queue.";
+		case DRMAA_ERRNO_RESUME_INCONSISTENT_STATE:
+			return "Can not resume job (not in valid state).";
+		case DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE:
+			return "Can not suspend job (not in valid state).";
+		case DRMAA_ERRNO_HOLD_INCONSISTENT_STATE:
+			return "Can not hold job (not in valid state).";
+		case DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE:
+			return "Can not release job (not in valid state).";
+		case DRMAA_ERRNO_EXIT_TIMEOUT:
+			return "Waiting for job to terminate finished due to time-out.";
+		case DRMAA_ERRNO_NO_RUSAGE:
+			return "Job finished but resource usage information "
+				"and/or termination status could not be provided.";
+		case DRMAA_ERRNO_NO_MORE_ELEMENTS:
+			return "Vector have no more elements.";
+
+		default:
+			return "Unknown DRMAA error code!?";
+	 }
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/compat.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/compat.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/compat.c	(revision 77)
@@ -0,0 +1,162 @@
+/* $Id: compat.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <drmaa_utils/compat.h>
+
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: compat.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+#ifndef HAVE_STRLCPY
+size_t
+strlcpy( char *dest, const char *src, size_t size )
+{
+	size_t result = 0;
+	if( size == 0 )
+		return 0;
+	while( *src  &&  --size > 0 )
+	 {
+		*dest++ = *src++;
+		result++;
+	 }
+	*dest++ = '\0';
+	return result;
+}
+#endif /* ! HAVE_STRLCPY */
+
+
+#ifndef HAVE_STRNDUP
+char *
+strndup( const char *s, size_t n )
+{
+	char *result;
+	if( s == NULL )
+		return NULL;
+	result = calloc( n + 1, sizeof(char) );
+
+	if( result == NULL )
+	 {
+		errno = ENOMEM;
+		return NULL;
+	 }
+
+	strlcpy( result, s, n + 1 );
+	return result;
+}
+#endif /* ! HAVE_STRNDUP */
+
+
+#ifndef HAVE_ASPRINTF
+int
+asprintf( char **strp, const char *fmt, ... )
+{
+	va_list args;
+	int result;
+	va_start( args, fmt );
+	result = vasprintf( strp, fmt, args );
+	va_end( args );
+	return result;
+}
+#endif /* ! HAVE_ASPRINTF */
+
+
+#ifndef HAVE_VASPRINTF
+int
+vasprintf( char **strp, const char *format, va_list ap )
+{
+	int size, check_size;
+	char *buf = NULL;
+
+#ifdef HAVE_VA_COPY
+	va_list aq;
+
+	va_copy(aq, ap);
+#else
+#  ifdef HAVE___VA_COPY
+	va_list aq;
+
+	__va_copy(aq, ap);
+#  endif
+#endif
+
+	*strp = NULL;
+
+#ifndef HAVE_C99_VSNPRINTF
+	{
+		int res;
+		char *tmp;
+
+		size = 128;
+		do {
+			size *= 2;
+			if (!(tmp = realloc(buf, size))) {
+				if (buf)
+					free(buf);
+				return -1;
+			}
+			buf = tmp;
+			/* XXX we're assuming here there's no va_copy on this system */
+			res = vsnprintf(buf, size, format, ap);
+		} while (res == -1);
+	}
+#else
+	{
+		char tmp[2];
+
+		/* on Solaris vsnprintf fails if buf is empty, so use a small one */
+		size = vsnprintf(tmp, sizeof(tmp), format, ap);
+		if (!(buf = malloc(size + 1)))
+			return -1;
+	}
+#endif
+
+#ifdef HAVE_VA_COPY
+	check_size = vsnprintf(buf, size + 1, format, aq);
+	va_end(aq);
+#else
+#  ifdef HAVE___VA_COPY
+	check_size = vsnprintf(buf, size + 1, format, aq);
+	va_end(aq);
+#  else
+	check_size = vsnprintf(buf, size + 1, format, ap);
+#  endif
+#endif
+	assert(check_size <= size);
+	*strp = buf;
+	return 0;
+}
+#endif
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_base.h	(revision 77)
@@ -0,0 +1,78 @@
+/* $Id: drmaa_base.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__DRMAA_BASE_H
+#define __DRMAA_UTILS__DRMAA_BASE_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/thread.h>
+
+#if 0
+struct fsd_drmaa_singletone_s {
+	/** Global session object */
+	fsd_drmaa_session_t *session;
+	fsd_mutex_t session_mutex;
+
+	fsd_drmaa_session_t *(*new_session)(
+			fsd_drmaa_singletone_t *self,
+			const char *contact
+			);
+
+	fsd_template_t *(*new_job_template)(
+			fsd_drmaa_singletone_t *self
+			);
+
+	const char* (*get_contact)( fsd_drmaa_singletone_t *self );
+	void (*get_version)(
+			fsd_drmaa_singletone_t *self,
+			unsigned *major, unsigned *minor
+			);
+	const char* (*get_DRM_system)( fsd_drmaa_singletone_t *self );
+	const char* (*get_DRMAA_implementation)( fsd_drmaa_singletone_t *self );
+
+	fsd_iter_t * (*
+	get_attribute_names)(
+		fsd_drmaa_singletone_t *self );
+
+	fsd_iter_t * (*
+	get_vector_attribute_names)(
+		fsd_drmaa_singletone_t *self );
+
+	int (*wifexited)( int *exited, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+	int (*wexitstatus)( int *exit_status, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+	int (*wifsignaled)( int *signaled, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+	int (*wtermsig)( char *signal, size_t signal_len, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+	int (*wcoredump)( int *core_dumped, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+	int (*wifaborted)( int *aborted, int stat,
+		char *error_diagnosis, size_t error_diag_len );
+};
+
+extern fsd_drmaa_singletone_t _fsd_drmaa_singletone;
+#endif
+
+#endif /* __DRMAA_UTILS__DRMAA_BASE_H */
Index: /branches/2.0/drmaa2_utils/drmaa_utils/environ.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/environ.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/environ.h	(revision 77)
@@ -0,0 +1,81 @@
+/* $Id: environ.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__ENVIRON_H
+#define __DRMAA_UTILS__ENVIRON_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/compat.h>
+
+typedef struct fsd_environ_s fsd_environ_t;
+typedef struct fsd_environ_item_s fsd_environ_item_t;
+
+struct fsd_environ_s {
+	void (*
+	destroy)( fsd_environ_t *self );
+
+	const char* (*
+	get)( fsd_environ_t *self, const char *name );
+
+	void (*
+	set)( fsd_environ_t *self, char *name, char *value );
+
+	void (*
+	update)( fsd_environ_t *self, const char *const envp[] );
+
+	char ** (*
+	list)( fsd_environ_t *self );
+
+	/**
+	 * Modifies process's environment overwriting variables
+	 * set in environ object.
+	 * @return  Dictionary of overwritten values.
+	 * @see #restore
+	 */
+	fsd_environ_t * (*
+	apply)( fsd_environ_t *self );
+
+	/**
+	 * Restore process's environment to original state.
+	 * All variables from \a self gets overwritten with values
+	 * from \a saved_state or unset if variable doesn't exist
+	 * in \a saved_state.
+	 * @see #apply
+	 */
+	void (*
+	restore)( fsd_environ_t *self, fsd_environ_t *saved_state );
+
+	fsd_environ_item_t **_table;
+	unsigned _table_size;
+};
+
+fsd_environ_t *
+fsd_environ_new( const char *const envp[] );
+
+struct fsd_environ_item_s {
+	fsd_environ_item_t *next;
+	char *name;
+	char *value;
+};
+
+#endif /* __DRMAA_UTILS__ENVIRON_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/drmaa_util.h	(revision 77)
@@ -0,0 +1,90 @@
+/* $Id: drmaa_util.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__DRMAA_UTIL_H
+#define __DRMAA_UTILS__DRMAA_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/common.h>
+
+enum{
+	FSD_DRMAA_PH_HD    = 1<<0,
+	FSD_DRMAA_PH_WD    = 1<<1,
+	FSD_DRMAA_PH_INCR  = 1<<2
+};
+
+struct fsd_expand_drmaa_ph_s {
+	/**
+	 * Expands placeholders in DRMAA job attribute value.
+	 * @param self   Context.
+	 * @param input  String to transform.  Should be malloc'ed
+	 *   and ownership is passed to callee.
+	 * @param set    Set of placeholders to expand.  Bitwise
+	 *   `or' of any of following bits:
+	 *   - FSD_DRMAA_PH_HD,
+	 *   - FSD_DRMAA_PH_WD,
+	 *   - FSD_DRMAA_PH_INCR
+	 * @return Value with expanded placeholders or \c NULL
+	 *   upon error.  Caller is responsible for free()'ing it.
+	 */
+	char *(*
+	expand)( fsd_expand_drmaa_ph_t *self, char *input, unsigned set );
+
+	void (*
+	set)( fsd_expand_drmaa_ph_t *self, int placeholder, char *value );
+
+	void (*destroy)( fsd_expand_drmaa_ph_t *self );
+
+	char *home_directory;
+	char *working_directory;
+	char *bulk_incr;
+};
+
+fsd_expand_drmaa_ph_t *
+fsd_expand_drmaa_ph_new(
+		char *home_directory,
+		char *working_directory,
+		char *bulk_incr
+		);
+
+int fsd_parse_timedelta( const char *string );
+
+/**
+ * Return textual representation of action
+ * - argument of drmaa_control().
+ */
+const char *drmaa_control_to_str( int action );
+
+/**
+ * Return textual representation of job status
+ * - result of drmaa_job_ps().
+ */
+const char *drmaa_job_ps_to_str( int ps );
+
+int fsd_drmaa_code( int fsd_errno );
+
+int fsd_errno_from_drmaa_code( int drmaa_errno );
+
+const char *fsd_drmaa_strerror( int drmaa_errno );
+
+#endif /* __DRMAA_UTILS__DRMAA_UTIL_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/compat.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/compat.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/compat.h	(revision 77)
@@ -0,0 +1,77 @@
+/* $Id: compat.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__COMPAT_H
+#define __DRMAA_UTILS__COMPAT_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#include <stddef.h>
+#include <stdarg.h>
+
+#ifdef HAVE_STDINT_H
+#	include <stdint.h>
+#else
+#	ifdef HAVE_INTTYPES_H
+#		include <inttypes.h>
+#	else
+#		warning "no stdint.h nor inttypes.h found"
+#	endif
+#endif /* ! HAVE_STDINT_H */
+
+#ifdef HAVE_STDBOOL_H
+#	include <stdbool.h>
+#else
+#	ifndef bool
+#		define bool int
+#	endif
+#	ifndef true
+#		define true 1
+#	endif
+#	ifndef false
+#		define false 0
+#	endif
+#endif /* ! HAVE_STDBOOL_H */
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy( char *dest, const char *src, size_t size )
+	__attribute__(( weak ));
+#endif
+
+#ifndef HAVE_STRNDUP
+char *strndup( const char *s, size_t n )
+	__attribute__(( weak ));
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf( char **strp, const char *fmt, ... )
+	__attribute__(( weak ));
+#endif
+
+#ifndef HAVE_VASPRINTF
+int vasprintf( char **strp, const char *fmt, va_list ap )
+	__attribute__(( weak ));
+#endif
+
+#endif /* __DRMAA_UTILS__COMPAT_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.c	(revision 77)
@@ -0,0 +1,644 @@
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashbig(), mix(), and final() are externally
+useful functions.  Routines to test the hash are included if SELF_TEST
+is defined.  You can use this free for any purpose.  It has no warranty.
+
+You probably want to use hashlittle().  hashlittle() and hashbig()
+hash byte arrays.  hashlittle() is is faster than hashbig() on
+little-endian machines.  Intel and AMD are little-endian machines.
+
+If you want to find a hash of, say, exactly 7 integers, do
+  a = i1;  b = i2;  c = i3;
+  mix(a,b,c);
+  a += i4; b += i5; c += i6;
+  mix(a,b,c);
+  a += i7;
+  final(a,b,c);
+then use c as the hash value.  If you have a variable length array of
+4-byte integers to hash, use hashword().  If you have a byte array (like
+a character string), use hashlittle().  If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+
+Code changed for ANSI C compilers and autotools by Åukasz CieÅnik.
+-------------------------------------------------------------------------------
+*/
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/lookup3.h>
+
+#ifdef SELF_TEST
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#endif
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: lookup3.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+typedef uint32_t uint32;   /* unsigned 4-byte quantities */
+typedef uint16_t uint16;   /* unsigned 2-byte quantities */
+typedef uint8_t  uint8;    /* unsigned 1-byte quantities */
+
+/* do not make any assumptions about the endianess - safer and prevents from reading not initialized memory */
+#	define HASH_LITTLE_ENDIAN 0
+#	define HASH_BIG_ENDIAN    0
+
+#define hashsize(n) ((uint32)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or
+  all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+    4  6  8 16 19  4
+    9 15  3 18 27 15
+   14  9  3  7 17  3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta.  I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche.  There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a.  The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism.  Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism.  I did what I could.  Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+  a -= c;  a ^= rot(c, 4);  c += b; \
+  b -= a;  b ^= rot(a, 6);  a += c; \
+  c -= b;  c ^= rot(b, 8);  b += a; \
+  a -= c;  a ^= rot(c,16);  c += b; \
+  b -= a;  b ^= rot(a,19);  a += c; \
+  c -= b;  c ^= rot(b, 4);  b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different.  This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+  of top bits of (a,b,c), or in any combination of bottom bits of
+  (a,b,c).
+* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed
+  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+  is commonly produced by subtraction) look like a single 1-bit
+  difference.
+* the base values were pseudorandom, all zero but one bit set, or
+  all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+  4  8 15 26 3 22 24
+ 10  8 15 26 3 22 24
+ 11  8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+  c ^= b; c -= rot(b,14); \
+  a ^= c; a -= rot(c,11); \
+  b ^= a; b -= rot(a,25); \
+  c ^= b; c -= rot(b,16); \
+  a ^= c; a -= rot(c,4);  \
+  b ^= a; b -= rot(a,14); \
+  c ^= b; c -= rot(b,24); \
+}
+
+/**
+ * This works on all machines.  To be useful, it requires
+ * -- that the key be an array of uint32's, and
+ * -- that all your machines have the same endianness, and
+ * -- that the length be the number of uint32's in the key
+
+ * The function hashword() is identical to hashlittle() on little-endian
+ * machines, and identical to hashbig() on big-endian machines,
+ * except that the length has to be measured in uint32s rather than in
+ * bytes.  hashlittle() is more complicated than hashword() only because
+ * hashlittle() has to dance around fitting the key bytes into registers.
+ *
+ * @param k          the key, an array of uint32 values
+ * @param length     the length of the key, in uint32s
+ * @param initval    the previous hash, or an arbitrary value
+ */
+uint32 hashword( const uint32 *k, size_t length, uint32 initval )
+{
+  uint32 a,b,c;
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + (((uint32)length)<<2) + initval;
+
+  /*------------------------------------------------- handle most of the key */
+  while (length > 3)
+  {
+    a += k[0];
+    b += k[1];
+    c += k[2];
+    mix(a,b,c);
+    length -= 3;
+    k += 3;
+  }
+
+  /*--------------------------------------------- handle the last 3 uint32's */
+  switch(length)                     /* all the case statements fall through */
+  {
+  case 3 : c+=k[2];
+  case 2 : b+=k[1];
+  case 1 : a+=k[0];
+    final(a,b,c);
+  case 0:     /* case 0: nothing left to add */
+    break;
+  }
+  /*------------------------------------------------------ report the result */
+  return c;
+}
+
+
+/**
+ * hashlittle() -- hash a variable-length key into a 32-bit value
+ *  @param k         the key (the unaligned variable-length array of bytes)
+ *  @param length    the length of the key, counting by bytes
+ *  @param initval   can be any 4-byte value
+ *
+ * Returns a 32-bit value.  Every bit of the key affects every bit of
+ * the return value.  Two keys differing by one or two bits will have
+ * totally different hash values.
+ *
+ * The best hash table sizes are powers of 2.  There is no need to do
+ * mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+ * use a bitmask.  For example, if you need only 10 bits, do
+ *   h = (h & hashmask(10));
+ * In which case, the hash table should have hashsize(10) elements.
+ *
+ * If you are hashing n strings (uint8 **)k, do it like this:
+ *   for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
+ *
+ * By Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this
+ * code any way you wish, private, educational, or commercial.  It's free.
+ *
+ * Use for hash table lookup, or anything where one collision in 2^^32 is
+ * acceptable.  Do NOT use for cryptographic purposes.
+ */
+uint32 hashlittle( const void *key, size_t length, uint32 initval )
+{
+  uint32 a,b,c;
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32)length) + initval;
+
+  if (HASH_LITTLE_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x3)) {
+    const uint32 *k = key;                                 /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+    case 5 : b+=k[1]&0xff; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]&0xffffff; break;
+    case 2 : a+=k[0]&0xffff; break;
+    case 1 : a+=k[0]&0xff; break;
+    case 0 : return c;              /* zero length strings require no mixing */
+    }
+
+  } else if (HASH_LITTLE_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x1)) {
+    const uint16 *k = key;                                   /* read 16-bit chunks */
+
+    /*--------------- all but last block: aligned reads and different mixing */
+    while (length > 12)
+    {
+      a += k[0] + (((uint32)k[1])<<16);
+      b += k[2] + (((uint32)k[3])<<16);
+      c += k[4] + (((uint32)k[5])<<16);
+      mix(a,b,c);
+      length -= 12;
+      k += 6;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    switch(length)
+    {
+    case 12: c+=k[4]+(((uint32)k[5])<<16);
+             b+=k[2]+(((uint32)k[3])<<16);
+             a+=k[0]+(((uint32)k[1])<<16);
+             break;
+    case 11: c+=((uint32)(k[5]&0xff))<<16;/* fall through */
+    case 10: c+=k[4];
+             b+=k[2]+(((uint32)k[3])<<16);
+             a+=k[0]+(((uint32)k[1])<<16);
+             break;
+    case 9 : c+=k[4]&0xff;                /* fall through */
+    case 8 : b+=k[2]+(((uint32)k[3])<<16);
+             a+=k[0]+(((uint32)k[1])<<16);
+             break;
+    case 7 : b+=((uint32)(k[3]&0xff))<<16;/* fall through */
+    case 6 : b+=k[2];
+             a+=k[0]+(((uint32)k[1])<<16);
+             break;
+    case 5 : b+=k[2]&0xff;                /* fall through */
+    case 4 : a+=k[0]+(((uint32)k[1])<<16);
+             break;
+    case 3 : a+=((uint32)(k[1]&0xff))<<16;/* fall through */
+    case 2 : a+=k[0];
+             break;
+    case 1 : a+=k[0]&0xff;
+             break;
+    case 0 : return c;                     /* zero length requires no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8 *k = key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      a += ((uint32)k[1])<<8;
+      a += ((uint32)k[2])<<16;
+      a += ((uint32)k[3])<<24;
+      b += k[4];
+      b += ((uint32)k[5])<<8;
+      b += ((uint32)k[6])<<16;
+      b += ((uint32)k[7])<<24;
+      c += k[8];
+      c += ((uint32)k[9])<<8;
+      c += ((uint32)k[10])<<16;
+      c += ((uint32)k[11])<<24;
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32)k[11])<<24;
+    case 11: c+=((uint32)k[10])<<16;
+    case 10: c+=((uint32)k[9])<<8;
+    case 9 : c+=k[8];
+    case 8 : b+=((uint32)k[7])<<24;
+    case 7 : b+=((uint32)k[6])<<16;
+    case 6 : b+=((uint32)k[5])<<8;
+    case 5 : b+=k[4];
+    case 4 : a+=((uint32)k[3])<<24;
+    case 3 : a+=((uint32)k[2])<<16;
+    case 2 : a+=((uint32)k[1])<<8;
+    case 1 : a+=k[0];
+             break;
+    case 0 : return c;
+    }
+  }
+
+  final(a,b,c);
+  return c;
+}
+
+
+
+/**
+ * hashbig():
+ * This is the same as hashword() on big-endian machines.  It is different
+ * from hashlittle() on all machines.  hashbig() takes advantage of
+ * big-endian byte ordering.
+ */
+uint32 hashbig( const void *key, size_t length, uint32 initval )
+{
+  uint32 a,b,c;
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32)length) + initval;
+
+  if (HASH_BIG_ENDIAN && !((((uint8 *)key)-(uint8 *)0) & 0x3)) {
+    const uint32 *k = key;                                 /* read 32-bit chunks */
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=k[2]<<8; b+=k[1]; a+=k[0]; break;
+    case 10: c+=k[2]<<16; b+=k[1]; a+=k[0]; break;
+    case 9 : c+=k[2]<<24; b+=k[1]; a+=k[0]; break;
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=k[1]<<8; a+=k[0]; break;
+    case 6 : b+=k[1]<<16; a+=k[0]; break;
+    case 5 : b+=k[1]<<24; a+=k[0]; break;
+    case 4 : a+=k[0]; break;
+    case 3 : a+=k[0]<<8; break;
+    case 2 : a+=k[0]<<16; break;
+    case 1 : a+=k[0]<<24; break;
+    case 0 : return c;              /* zero length strings require no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8 *k = key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += ((uint32)k[0])<<24;
+      a += ((uint32)k[1])<<16;
+      a += ((uint32)k[2])<<8;
+      a += ((uint32)k[3]);
+      b += ((uint32)k[4])<<24;
+      b += ((uint32)k[5])<<16;
+      b += ((uint32)k[6])<<8;
+      b += ((uint32)k[7]);
+      c += ((uint32)k[8])<<24;
+      c += ((uint32)k[9])<<16;
+      c += ((uint32)k[10])<<8;
+      c += ((uint32)k[11]);
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32)k[11])<<24;
+    case 11: c+=((uint32)k[10])<<16;
+    case 10: c+=((uint32)k[9])<<8;
+    case 9 : c+=k[8];
+    case 8 : b+=((uint32)k[7])<<24;
+    case 7 : b+=((uint32)k[6])<<16;
+    case 6 : b+=((uint32)k[5])<<8;
+    case 5 : b+=k[4];
+    case 4 : a+=((uint32)k[3])<<24;
+    case 3 : a+=((uint32)k[2])<<16;
+    case 2 : a+=((uint32)k[1])<<8;
+    case 1 : a+=k[0];
+             break;
+    case 0 : return c;
+    }
+  }
+
+  final(a,b,c);
+  return c;
+}
+
+
+#ifdef SELF_TEST
+
+/* used for timings */
+void driver1(void)
+{
+  uint8 buf[256];
+  uint32 i;
+  uint32 h=0;
+  time_t a,z;
+
+  time(&a);
+  for (i=0; i<256; ++i) buf[i] = 'x';
+  for (i=0; i<1; ++i)
+  {
+    h = hashlittle(&buf[0],1,h);
+  }
+  time(&z);
+  if (z-a > 0) printf("time %ld %.8lx\n", z-a, h);
+}
+
+/* check that every input bit changes every output bit half the time */
+#define HASHSTATE 1
+#define HASHLEN   1
+#define MAXPAIR 60
+#define MAXLEN  70
+void driver2(void)
+{
+  uint8 qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];
+  uint32 c[HASHSTATE], d[HASHSTATE], i, j=0, k, l, m, z;
+  uint32 e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];
+  uint32 x[HASHSTATE],y[HASHSTATE];
+  uint32 hlen;
+
+  printf("No more than %d trials should ever be needed \n",MAXPAIR/2);
+  for (hlen=0; hlen < MAXLEN; ++hlen)
+  {
+    z=0;
+    for (i=0; i<hlen; ++i)  /*----------------------- for each input byte, */
+    {
+      for (j=0; j<8; ++j)   /*------------------------ for each input bit, */
+      {
+	for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
+	{
+	  for (l=0; l<HASHSTATE; ++l) e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32)0);
+
+		/*---- check that every output bit is affected by that input bit */
+	  for (k=0; k<MAXPAIR; k+=2)
+	  {
+	    uint32 finished=1;
+	    /* keys have one bit different */
+	    for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8)0;}
+	    /* have a and b be two keys differing in only one bit */
+	    a[i] ^= (k<<j);
+	    a[i] ^= (k>>(8-j));
+	     c[0] = hashlittle(a, hlen, m);
+	    b[i] ^= ((k+1)<<j);
+	    b[i] ^= ((k+1)>>(8-j));
+	     d[0] = hashlittle(b, hlen, m);
+	    /* check every bit is 1, 0, set, and not set at least once */
+	    for (l=0; l<HASHSTATE; ++l)
+	    {
+	      e[l] &= (c[l]^d[l]);
+	      f[l] &= ~(c[l]^d[l]);
+	      g[l] &= c[l];
+	      h[l] &= ~c[l];
+	      x[l] &= d[l];
+	      y[l] &= ~d[l];
+	      if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
+	    }
+	    if (finished) break;
+	  }
+	  if (k>z) z=k;
+	  if (k==MAXPAIR) 
+	  {
+	     printf("Some bit didn't change: ");
+	     printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx  ",
+	            e[0],f[0],g[0],h[0],x[0],y[0]);
+	     printf("i %ld j %ld m %ld len %ld\n",i,j,m,hlen);
+	  }
+	  if (z==MAXPAIR) goto done;
+	}
+      }
+    }
+   done:
+    if (z < MAXPAIR)
+    {
+      printf("Mix success  %2ld bytes  %2ld initvals  ",i,m);
+      printf("required  %ld  trials\n",z/2);
+    }
+  }
+  printf("\n");
+}
+
+/* Check for reading beyond the end of the buffer and alignment problems */
+void driver3(void)
+{
+  uint8 buf[MAXLEN+20], *b;
+  uint32 len;
+  uint8 q[] = "This is the time for all good men to come to the aid of their country...";
+  uint32 dummy1;
+  uint8 qq[] = "xThis is the time for all good men to come to the aid of their country...";
+  uint32 dummy2;
+  uint8 qqq[] = "xxThis is the time for all good men to come to the aid of their country...";
+  uint32 dummy3;
+  uint8 qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";
+  uint32 h,i,j,ref,x,y;
+  uint8 *p;
+
+  printf("Endianness.  These lines should all be the same (for values filled in):\n");
+  printf("%.8lx                            %.8lx                            %.8lx\n",
+         hashword((uint32 *)q, (sizeof(q)-1)/4, 13),
+         hashword((uint32 *)q, (sizeof(q)-5)/4, 13),
+         hashword((uint32 *)q, (sizeof(q)-9)/4, 13));
+  p = q;
+  printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qq[1];
+  printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qqq[2];
+  printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  p = &qqqq[3];
+  printf("%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
+         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),
+         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),
+         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),
+         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),
+         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),
+         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));
+  printf("\n");
+  for (h=0, b=buf+1; h<8; ++h, ++b)
+  {
+    for (i=0; i<MAXLEN; ++i)
+    {
+      len = i;
+      for (j=0; j<i; ++j) *(b+j)=0;
+
+      /* these should all be equal */
+      ref = hashlittle(b, len, (uint32)1);
+      *(b+i)=(uint8)~0;
+      *(b-1)=(uint8)~0;
+      x = hashlittle(b, len, (uint32)1);
+      y = hashlittle(b, len, (uint32)1);
+      if ((ref != x) || (ref != y)) 
+      {
+	printf("alignment error: %.8lx %.8lx %.8lx %ld %ld\n",ref,x,y,h,i);
+      }
+    }
+  }
+}
+
+/* check for problems with nulls */
+ void driver4(void)
+{
+  uint8 buf[1];
+  uint32 h,i,state[HASHSTATE];
+
+
+  buf[0] = ~0;
+  for (i=0; i<HASHSTATE; ++i) state[i] = 1;
+  printf("These should all be different\n");
+  for (i=0, h=0; i<8; ++i)
+  {
+    h = hashlittle(buf, (uint32)0, h);
+    printf("%2ld  0-byte strings, hash is  %.8lx\n", i, h);
+  }
+}
+
+
+int main()
+{
+  driver1();   /* test that the key is hashed: used for timings */
+  driver2();   /* test that whole key is hashed thoroughly */
+  driver3();   /* test that nothing but the key is hashed */
+  driver4();   /* test hashing multiple buffers (all buffers are null) */
+  return 1;
+}
+
+#endif  /* SELF_TEST */
Index: /branches/2.0/drmaa2_utils/drmaa_utils/common.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/common.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/common.h	(revision 77)
@@ -0,0 +1,53 @@
+/* $Id: common.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__COMMON_H
+#define __DRMAA_UTILS__COMMON_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/compat.h>
+#include <drmaa_utils/exception.h>
+#include <drmaa_utils/logging.h>
+#include <drmaa_utils/xmalloc.h>
+
+#define FSD_SAFE_STR(str) ( str != NULL ? str : "(null)" )
+
+/* configuration */
+typedef struct fsd_conf_option_s  fsd_conf_option_t;
+typedef struct fsd_conf_dict_s    fsd_conf_dict_t;
+
+/* iterator */
+typedef struct fsd_iter_s fsd_iter_t;
+
+/* template type */
+typedef struct fsd_attribute_s  fsd_attribute_t;
+typedef struct fsd_template_s   fsd_template_t;
+
+/* DRMAA structures */
+typedef struct fsd_drmaa_singletone_s  fsd_drmaa_singletone_t;
+typedef struct fsd_drmaa_session_s     fsd_drmaa_session_t;
+typedef struct fsd_job_set_s           fsd_job_set_t;
+typedef struct fsd_job_s               fsd_job_t;
+typedef struct fsd_expand_drmaa_ph_s   fsd_expand_drmaa_ph_t;
+
+#endif /* __DRMAA_UTILS__COMMON_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/exception.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/exception.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/exception.c	(revision 77)
@@ -0,0 +1,614 @@
+/* $Id: exception.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <pthread.h>
+
+#include <drmaa_utils/common.h>
+#include <drmaa_utils/exception.h>
+
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: exception.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+int fsd_exc_code( const fsd_exc_t *self );
+const char *fsd_exc_message( const fsd_exc_t *self );
+void fsd_exc_destroy( fsd_exc_t *self );
+
+#define EXC_INITIALIZER( code, message ) \
+ { \
+	fsd_exc_code, fsd_exc_message, fsd_exc_destroy, \
+	code, message, false, false \
+ }
+
+static const fsd_exc_t no_memory_exception \
+	= EXC_INITIALIZER( FSD_ERRNO_NO_MEMORY, "Not enough memory." );
+
+
+/**
+ * Thread specific stack of restore points
+ * @see fsd_exc_try_block_t
+ */
+typedef struct fsd_exc_stack_s {
+	fsd_exc_try_block_t **restore_points;
+	int n_restore_points;
+} fsd_exc_stack_t;
+
+
+static pthread_key_t fsd_exc_stack;
+static pthread_once_t fsd_exc_init_once = PTHREAD_ONCE_INIT;
+
+
+static void
+fsd_exc_stack_destroy( fsd_exc_stack_t *stack );
+
+
+void
+fsd_exc_init(void)
+{
+	int rc;
+	fsd_log_enter((""));
+	rc = pthread_key_create(
+			&fsd_exc_stack,
+			(void (*)(void*))fsd_exc_stack_destroy
+			);
+	if( rc )
+	 {
+		char errbuf[256] = "InternalError";
+		(void)strerror_r(errno, errbuf, 256);
+		fsd_log_fatal(( "pthread_key_create: %s",errbuf ));
+		abort();
+	 }
+	fsd_log_return((""));
+}
+
+
+fsd_exc_stack_t *
+fsd_exc_get_stack( bool create )
+{
+	fsd_exc_stack_t *stack = NULL;
+	int rc;
+
+	rc = pthread_once( &fsd_exc_init_once, fsd_exc_init );
+	if( rc )
+	 {
+		char errbuf[256] = "InternalError";
+		(void)strerror_r(errno, errbuf, 256);
+		fsd_log_fatal(( "pthread_once: %s",errbuf));
+		abort();
+	 }
+	stack = (fsd_exc_stack_t*)pthread_getspecific( fsd_exc_stack );
+	if( stack == NULL  &&  create )
+	 {
+		rc = fsd_malloc_noraise( stack, fsd_exc_stack_t );
+		if( rc )  return NULL;
+		stack->restore_points = NULL;
+		stack->n_restore_points = 0;
+		rc = pthread_setspecific( fsd_exc_stack, stack );
+		if( rc  &&  errno != ENOMEM )
+		 {
+			char errbuf[256] = "InternalError";
+			(void)strerror_r(errno, errbuf, 256);
+			fsd_log_fatal(( "pthread_setspecific: %s",errbuf ));
+			abort();
+		 }
+		else if( rc )
+		 {
+			fsd_exc_stack_destroy( stack );
+		 }
+	 }
+	else
+		fsd_assert( stack != NULL );
+	return stack;
+}
+
+
+void
+fsd_exc_stack_destroy( fsd_exc_stack_t *stack )
+{
+	int i;
+	fsd_log_enter((""));
+	for( i = 0;  i < stack->n_restore_points;  i++ )
+	 {
+		fsd_exc_try_block_t *b = stack->restore_points[i];
+		if( b->handled_exc != NULL )
+			b->handled_exc->destroy( b->handled_exc );
+		fsd_free( b );
+	 }
+	fsd_free( stack->restore_points );
+	fsd_free( stack );
+	fsd_log_return((""));
+}
+
+
+fsd_exc_try_block_t *
+fsd_exc_try( const char *function, int lineno )
+{
+	fsd_exc_stack_t *stack = NULL;
+	fsd_exc_try_block_t *p = NULL;
+	int rc;
+
+	/* fsd_log_enter(( "(%s, %d)", function, lineno )); */
+	stack = fsd_exc_get_stack( true );
+	if( stack == NULL )
+		return NULL;
+
+	rc = fsd_realloc_noraise(
+			stack->restore_points, stack->n_restore_points+1,
+			fsd_exc_try_block_t* );
+	if( rc )
+		return NULL;
+	rc = fsd_malloc_noraise( p, fsd_exc_try_block_t );
+	if( rc )
+		return NULL;
+	p->handled_exc = NULL;
+	p->state = FSD_EXC_ENTER;
+	p->function = function;
+	p->lineno = lineno;
+	stack->restore_points[ stack->n_restore_points++ ] = p;
+	/* fsd_log_return(( " =%p", (void*)p )); */
+	return p;
+}
+
+
+void
+fsd_exc_control( fsd_exc_try_block_t *block, int *rc )
+{
+	/* fsd_log_enter(( "(block=%p, rc=%d)", (void*)block, *rc )); */
+	if( block == NULL  ||  *rc == FSD_ERRNO_EXC_END )
+		return;
+
+	switch( block->state )
+	 {
+		case FSD_EXC_ENTER:
+			block->state = FSD_EXC_TRY_BLOCK;
+			fsd_assert( *rc == 0 );
+			/* fsd_log_return(( ": rc=%d => %s:%d",
+						*rc, block->function, block->lineno )); */
+			return;
+
+		case FSD_EXC_TRY_BLOCK:
+			if( *rc == 0 )
+			 {
+				block->state = FSD_EXC_ELSE_BLOCK;
+				/* fsd_log_return(( ": rc=FSD_ERRNO_EXC_ELSE => %s:%d",
+							block->function, block->lineno )); */
+				*rc = FSD_ERRNO_EXC_ELSE;
+				return;
+			 }
+			else
+			 {
+				fsd_assert( *rc > 0 );
+				block->state = FSD_EXC_EXCEPTION_HANDLE;
+				/* fsd_log_return(( ": rc=%d => %s:%d",
+							*rc, block->function, block->lineno )); */
+				return;
+			 }
+
+		case FSD_EXC_EXCEPTION_HANDLE:
+		case FSD_EXC_ELSE_BLOCK:
+			block->state = FSD_EXC_FINALLY_BLOCK;
+			/* fsd_log_return(( ": rc=FSD_ERRNO_EXC_FINALLY => %s:%d",
+						block->function, block->lineno )); */
+			*rc = FSD_ERRNO_EXC_FINALLY;
+			return;
+
+		case FSD_EXC_FINALLY_BLOCK:
+		 {
+			fsd_exc_try_block_t *current = NULL;
+			fsd_exc_try_block_t *upper = NULL;
+			fsd_exc_stack_t *stack = NULL;
+
+			block->state = FSD_EXC_LEAVE;
+
+			stack = fsd_exc_get_stack( false );
+			current = stack->restore_points[ stack->n_restore_points-1 ];
+			fsd_assert( block == current );
+			if( stack->n_restore_points > 1 )
+				upper = stack->restore_points[ stack->n_restore_points-2 ];
+			stack->n_restore_points --;
+
+			if( current->handled_exc  &&  upper )
+			 {
+				if( upper->handled_exc )
+				 {
+					fsd_assert( upper->state == FSD_EXC_EXCEPTION_HANDLE
+							|| upper->state == FSD_EXC_FINALLY_BLOCK );
+					if( upper->state == FSD_EXC_FINALLY_BLOCK )
+						fsd_log_warning((
+									"overriding previously raised exception: <%d:%s>",
+									upper->handled_exc->_code, upper->handled_exc->_message ));
+					upper->handled_exc->destroy( upper->handled_exc );
+				 }
+				upper->handled_exc = current->handled_exc;
+				/* current->handled_exc = NULL; */
+				fsd_free_noraise( current );
+				/* fsd_log_return(( ": longjmp(..., %d) => %s:%d",
+							upper->handled_exc->_code, upper->function, upper->lineno )); */
+				longjmp( upper->env, upper->handled_exc->_code );
+			 }
+			else
+			 {
+				if( current->handled_exc )
+					current->handled_exc->destroy( current->handled_exc );
+				fsd_free_noraise( current );
+				/* fsd_log_return(( ": rc=FSD_ERRNO_EXC_END => %s:%d",
+							block->function, block->lineno )); */
+				*rc = FSD_ERRNO_EXC_END;
+				return;
+			 }
+		 }
+
+		default:
+			fsd_assert(false);
+	 }
+
+	/* no return */
+}
+
+
+const fsd_exc_t *
+fsd_exc_get(void)
+{
+	fsd_exc_stack_t *stack;
+	fsd_exc_try_block_t *block;
+	stack = fsd_exc_get_stack( false );
+	fsd_assert( stack->n_restore_points > 0 );
+	block = stack->restore_points[ stack->n_restore_points-1 ];
+	return block->handled_exc;
+}
+
+
+void
+fsd_exc_clear(void)
+{
+	fsd_exc_stack_t *stack;
+	fsd_exc_try_block_t *block;
+	fsd_log_enter((""));
+	stack = fsd_exc_get_stack( false );
+	fsd_assert( stack->n_restore_points > 0 );
+	block = stack->restore_points[ stack->n_restore_points-1 ];
+	if( block->handled_exc )
+		block->handled_exc->destroy( block->handled_exc );
+	block->handled_exc = NULL;
+	fsd_log_return((""));
+}
+
+
+fsd_exc_t *
+fsd_exc_new( int code, char *message, bool own_message )
+{
+	fsd_exc_t *exc = NULL;
+	char *volatile message_buffer = NULL;
+
+	if ( code == FSD_DRMAA_ERRNO_EXIT_TIMEOUT || code == FSD_ERRNO_STOP_ITERATION ) 
+		fsd_log_debug(("fsd_exc_new(%d,%s,%d)", code, message, own_message));
+	else
+		fsd_log_error(("fsd_exc_new(%d,%s,%d)", code, message, own_message));
+
+
+	TRY
+	 {
+		if( own_message )
+			message_buffer = message;
+		fsd_malloc( exc, fsd_exc_t );
+		exc->_code = code;
+		exc->_message = message;
+		exc->_own_message = own_message;
+		exc->_own_self = true;
+		exc->code = fsd_exc_code;
+		exc->message = fsd_exc_message;
+		exc->destroy = fsd_exc_destroy;
+	 }
+	EXCEPT_DEFAULT
+	 {
+		fsd_free( message_buffer );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+	return exc;
+}
+
+int
+fsd_exc_code( const fsd_exc_t *self )
+{
+	return self->_code;
+}
+
+const char *
+fsd_exc_message( const fsd_exc_t *self )
+{
+	return self->_message;
+}
+
+void
+fsd_exc_destroy( fsd_exc_t *self )
+{
+	if( self->_own_message )
+		fsd_free_noraise( self->_message );
+	if( self->_own_self )
+		fsd_free_noraise( self );
+}
+
+
+void
+fsd_exc_raise( fsd_exc_t *exc )
+{
+	fsd_exc_stack_t *stack = NULL;
+	fsd_exc_try_block_t *block = NULL;
+	fsd_assert(( exc->_code > 0 ));
+	stack = fsd_exc_get_stack( false );
+	fsd_assert(( stack->n_restore_points > 0 ));
+	block = stack->restore_points[ stack->n_restore_points - 1 ];
+	if( block->handled_exc )
+		block->handled_exc->destroy( block->handled_exc );
+	block->handled_exc = exc;
+	longjmp( block->env, exc->_code );
+}
+
+
+void
+fsd_exc_raise_code( int error_code )
+{
+	fsd_exc_t *exc;
+
+	if( error_code == FSD_ERRNO_NO_MEMORY )
+		exc = (fsd_exc_t*)&no_memory_exception;
+	else
+		exc = fsd_exc_new( error_code, (char*)fsd_strerror(error_code), false );
+	fsd_exc_raise( exc );
+}
+
+void
+fsd_exc_raise_msg( int error_code, const char *message )
+{
+	fsd_exc_raise(
+			fsd_exc_new( error_code, fsd_strdup(message), true ) );
+}
+
+void
+fsd_exc_raise_fmt( int error_code, const char *fmt, ... )
+{
+	va_list args;
+	va_start( args, fmt );
+	fsd_exc_raise_fmtv( error_code, fmt, args );
+	va_end( args );
+}
+
+void
+fsd_exc_raise_fmtv( int error_code, const char *fmt, va_list args )
+{
+	fsd_exc_t *exc = NULL;
+	char *volatile message = NULL;
+	TRY
+	 {
+		message = fsd_vasprintf( fmt, args );
+		exc = fsd_exc_new( error_code, message, true );
+		message = NULL;
+	 }
+	FINALLY
+	 {
+		fsd_free( message );
+	 }
+	END_TRY
+	fsd_exc_raise( exc );
+}
+
+void
+fsd_exc_raise_sys( int errno_code )
+{
+	fsd_exc_t *exc = NULL;
+
+	if( errno_code == 0 )
+		errno_code = errno;
+	if( errno_code == ENOMEM )
+		exc = (fsd_exc_t*)&no_memory_exception;
+	else
+	 {
+		int code;
+		char* volatile message = NULL;
+		volatile bool own_message = false;
+		TRY
+		 {
+			switch( errno_code )
+			 {
+				case ETIMEDOUT:  code = FSD_ERRNO_TIMEOUT;  break;
+				default:         code = FSD_ERRNO_INTERNAL_ERROR;  break;
+			 }
+			message = (char*)fsd_astrerror( errno_code, (bool*)&own_message );
+			exc = fsd_exc_new( code, message, own_message );
+		 }
+		EXCEPT_DEFAULT
+		 {
+			if( message && own_message )
+				fsd_free( message );
+			fsd_exc_reraise();
+		 }
+		END_TRY
+	 }
+	fsd_exc_raise( exc );
+}
+
+
+void
+fsd_exc_reraise(void)
+{
+	fsd_exc_stack_t *stack = NULL;
+	fsd_exc_try_block_t *block = NULL;
+	stack = fsd_exc_get_stack( false );
+	fsd_assert(( stack->n_restore_points > 0 ));
+	block = stack->restore_points[ stack->n_restore_points - 1 ];
+	fsd_assert(( block->handled_exc->_code > 0 ));
+	longjmp( block->env, block->handled_exc->_code );
+}
+
+
+const char *
+fsd_strerror( int error_code )
+{
+	switch( error_code )
+	 {
+		case FSD_ERRNO_SUCCESS:
+			return "Success.";
+		case FSD_ERRNO_INTERNAL_ERROR:
+			return "Unexpected or internal error.";
+		case FSD_ERRNO_NO_MEMORY:
+			return "Not enough memory.";
+		case FSD_ERRNO_INVALID_ARGUMENT:
+			return "Invalid argument value.";
+		case FSD_ERRNO_INVALID_VALUE:
+			return "Invalid value.";
+		case FSD_ERRNO_INVALID_VALUE_FORMAT:
+			return "Invalid value format.";
+		case FSD_ERRNO_STOP_ITERATION:
+			return "Vector have no more elements.";
+		case FSD_ERRNO_NOT_IMPLEMENTED:
+			return "Functionality is not implemented.";
+		case FSD_ERRNO_NOT_INITIALIZED:
+			return "Library is not initialized";
+		case FSD_ERRNO_TIMEOUT:
+			return "Routine returned due to time-out.";
+		case FSD_ERRNO_AUTH_FAILURE:
+			return "Authentication failure.";
+		case FSD_ERRNO_AUTHZ_FAILURE:
+			return "Authorization failure";
+		case FSD_ERRNO_TRY_LATER:
+			return "System is overloaded.  Try again later.";
+		case FSD_ERRNO_DRM_COMMUNICATION_FAILURE:
+			return "Could not contact DRM system for this request.";
+		case FSD_ERRNO_DRMS_INIT_FAILED:
+			return "Unable to initialize DRM system.";
+		case FSD_ERRNO_DRMS_EXIT_ERROR:
+			return "Disengagement from the DRM system failed.";
+		case FSD_ERRNO_DENIED_BY_DRM:
+			return "DRM rejected request due to its configuration "
+				"or request attributes.";
+
+		case FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION:
+			return "No active DRMAA session.";
+		case FSD_DRMAA_ERRNO_INVALID_CONTACT_STRING:
+			return "Invalid contact string.";
+		case FSD_DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR:
+			return "Can not determine default contact to DRM system.";
+		case FSD_DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED:
+			return "Contact to DRM must be set explicitly "
+				"because there is no default.";
+		case FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION:
+			return "DRMAA session already exist.";
+		case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT:
+			return "Invalid format of job attribute.";
+		case FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE:
+			return "Invalid value of job attribute.";
+		case FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES:
+			return "Value of attribute conflicts with other attribute value.";
+		case FSD_DRMAA_ERRNO_INVALID_JOB:
+			return "Job does not exist in DRMs queue.";
+		case FSD_DRMAA_ERRNO_RESUME_INCONSISTENT_STATE:
+			return "Can not resume job (not in valid state).";
+		case FSD_DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE:
+			return "Can not suspend job (not in valid state).";
+		case FSD_DRMAA_ERRNO_HOLD_INCONSISTENT_STATE:
+			return "Can not hold job (not in valid state).";
+		case FSD_DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE:
+			return "Can not release job (not in valid state).";
+		case FSD_DRMAA_ERRNO_EXIT_TIMEOUT:
+			return "Waiting for job to terminate finished due to time-out.";
+		case FSD_DRMAA_ERRNO_NO_RUSAGE:
+			return "Job finished but resource usage information "
+				"and/or termination status could not be provided.";
+
+		case FSD_ARES_ERRNO_INVALID_CONTACT_STRING:
+			return "Invalid contact string.";
+		case FSD_ARES_ERRNO_INVALID_ATTRIBUTE_FORMAT:
+			return "Invalid format of job attribute.";
+		case FSD_ARES_ERRNO_INVALID_ATTRIBUTE_VALUE:
+			return "Invalid value of job attribute.";
+		case FSD_ARES_ERRNO_CONFLICTING_ATTRIBUTE_VALUES:
+			return "Value of attribute conflicts with other attribute value.";
+		case FSD_ARES_ERRNO_INVALID_ARES:
+			return "Invalid advance reservation identifier..";
+
+		default:
+			return "Unknown error code!?";
+	 }
+}
+
+
+static const int fsd_stacktrace_length = 32;
+
+void
+fsd_assertion_failed(
+		const char *file, int lineno,
+		const char *function, const char *precondition
+		)
+{
+	char *message = NULL;
+	if( asprintf( &message, "%s:%d: %s: Assertion `%s' failed.",
+			file, lineno, function, precondition ) == -1 )
+		message = NULL;
+	if( message != NULL )
+		fsd_log_fatal(( "%s", message ));
+	fsd_log_stacktrace( 1, fsd_stacktrace_length );
+	if( message != NULL )
+		free( message );
+	abort();
+}
+
+
+void *
+fsd_exc_try_except(
+		void*(*f)(void*), void *data,
+		int *error_code,
+		char **error_message
+		)
+{
+	void *result = NULL;
+	TRY
+	 {
+		result = f( data );
+	 }
+	EXCEPT_DEFAULT
+	 {
+		const fsd_exc_t *e = fsd_exc_get();
+		*error_code = e->code(e);
+		*error_message = fsd_strdup( e->message(e) );
+	 }
+	ELSE
+	 {
+		*error_code = FSD_ERRNO_SUCCESS;
+		*error_message = NULL;
+	 }
+	END_TRY
+	return result;
+}
+
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/lookup3.h	(revision 77)
@@ -0,0 +1,25 @@
+/* $Id: lookup3.h 13 2011-04-20 15:41:43Z mmamonski $ */
+
+#ifndef __LOOKUP3_H
+#define __LOOKUP3_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/compat.h>
+
+uint32_t hashword( const uint32_t *k, size_t length, uint32_t initval );
+uint32_t hashlittle( const void *key, size_t length, uint32_t initval );
+uint32_t hashbig( const void *key, size_t length, uint32_t initval );
+
+#if BYTEORDER == 1234 /* little endian */
+#	define hashstr hashlittle
+#endif
+
+#if BYTEORDER == 4321  /* big endian */
+#	define hashstr hashbig
+#endif
+
+#endif /* __LOOKUP3_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.y
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.y	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/conf_tab.y	(revision 77)
@@ -0,0 +1,140 @@
+/* $Id: conf_tab.y 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *
+ * PSNC DRMAA 2.0 utilities library
+ * Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+%{
+#ifdef HAVE_MALLOC_H
+#       include <malloc.h>
+#endif
+#include <drmaa_utils/conf_impl.h>
+#include <drmaa_utils/conf_tab.h>
+%}
+
+%pure-parser
+%locations
+%name-prefix="fsd_conf_"
+%parse-param { fsd_conf_parser_t *parser }
+%parse-param { fsd_conf_lexer_t *lexer }
+%lex-param { fsd_conf_lexer_t *lexer }
+
+
+%union {
+	int integer;
+	char *string;
+	fsd_conf_option_t *option;
+	fsd_conf_dict_t *dictionary;
+	fsd_conf_pair_t pair;
+}
+
+%type<option> value
+%destructor { fsd_conf_option_destroy($$); } value
+%type<dictionary> start conf dict dict_body pair_list
+%destructor { fsd_conf_dict_destroy($$); } conf dict dict_body pair_list
+%type<pair> pair
+%token<integer> INTEGER
+%token<string> STRING
+%destructor { free($$); } STRING
+%token LEXER_ERROR
+
+
+%%
+
+start
+	: conf { parser->result = $1;  $$ = NULL; }
+	;
+
+conf
+	: dict
+	| dict_body
+	;
+
+dict
+	: '{' dict_body '}' { $$ = $2; }
+	;
+
+dict_body
+	: pair_list  { $$ = $1; }
+	| pair_list ','  { $$ = $1; }
+	| {
+		$$ = fsd_conf_dict_create_noraise();
+		if( $$ == NULL )  YYABORT;
+	}
+	;
+
+pair_list
+	: pair
+		 {
+			fsd_conf_dict_t *dict = NULL;
+			int rc;
+			dict = fsd_conf_dict_create_noraise();
+			if( dict == NULL )
+				YYABORT;
+			rc = fsd_conf_dict_set_noraise( dict, $1.key, $1.value );
+			if( rc )
+			 {
+				fsd_conf_dict_destroy( dict );
+				YYABORT;
+			 }
+			$$ = dict;
+		 }
+	| pair_list ',' pair
+		 {
+			int rc;
+			rc = fsd_conf_dict_set_noraise( $1, $3.key, $3.value );
+			if( rc )
+				YYABORT;
+			$$ = $1; /* explicit no op */
+		 }
+	;
+
+pair
+	: STRING ':' value { $$.key = $1;  $$.value = $3; }
+	;
+
+value
+	: INTEGER
+		 {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_INTEGER, &$1 );
+			if( o )
+				$$ = o;
+			else
+				YYABORT;
+		 }
+	| STRING
+		 {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_STRING, $1 );
+			if( o )
+				$$ = o;
+			else
+				YYABORT;
+		 }
+	| dict
+		 {
+			fsd_conf_option_t *o;
+			o = fsd_conf_option_create_noraise( FSD_CONF_DICT, $1 );
+			if( o )
+				$$ = o;
+			else
+				YYABORT;
+		 }
+	;
+
+%%
Index: /branches/2.0/drmaa2_utils/drmaa_utils/iter.c
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/iter.c	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/iter.c	(revision 77)
@@ -0,0 +1,145 @@
+/* $Id: iter.c 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <drmaa_utils/iter.h>
+
+#ifndef lint
+static char rcsid[]
+#	ifdef __GNUC__
+		__attribute__ ((unused))
+#	endif
+	= "$Id: iter.c 13 2011-04-20 15:41:43Z mmamonski $";
+#endif
+
+
+static const char *
+fsd_iter_next( fsd_iter_t *self )
+{
+	if( self->_position < self->_length )
+		return self->_list[ self->_position++ ];
+	else
+		fsd_exc_raise_code( FSD_ERRNO_STOP_ITERATION );
+}
+
+static void
+fsd_iter_reset( fsd_iter_t *self )
+{
+	self->_length = 0;
+}
+
+static int
+fsd_iter_len( fsd_iter_t *self )
+{
+	return self->_length;
+}
+
+static void
+fsd_iter_append( fsd_iter_t *self, char *string )
+{
+	TRY
+	 {
+		if( !self->_own_list )
+			fsd_exc_raise_msg(
+					FSD_ERRNO_INTERNAL_ERROR,
+					"iter::append called on constant list" );
+		fsd_realloc( self->_list, self->_length+1, char* );
+		self->_list[ self->_length++ ] = string;
+	 }
+	EXCEPT_DEFAULT
+	 {
+		fsd_free( string );
+		fsd_exc_reraise();
+	 }
+	END_TRY
+}
+
+static void
+fsd_iter_destroy( fsd_iter_t *self )
+{
+	int i;
+	if( self->_own_list  &&  self->_list )
+	 {
+		for( i = 0;  i < self->_length;  i++ )
+			fsd_free( self->_list[i] );
+		fsd_free( self->_list );
+	 }
+	fsd_free( self );
+}
+
+static fsd_iter_t *
+fsd_iter_new_impl( char **list, int length, bool own )
+{
+	fsd_iter_t *volatile self = NULL;
+	TRY
+	 {
+		fsd_malloc( self, fsd_iter_t );
+		self->next = fsd_iter_next;
+		self->reset = fsd_iter_reset;
+		self->len = fsd_iter_len;
+		self->append = fsd_iter_append;
+		self->destroy = fsd_iter_destroy;
+		self->_list = list;
+		self->_position = 0;
+		if( list == NULL )
+			self->_length = 0;
+		else if( length >= 0 )
+			self->_length = length;
+		else
+		 {
+			char **i;
+			int cnt = 0;
+			for( i = self->_list;  *i != NULL;  i++ )
+				cnt++;
+			self->_length = cnt;
+		 }
+		self->_own_list = own;
+	 }
+	EXCEPT_DEFAULT
+	 {
+		if( own  &&  list )
+		 {
+			if( length >= 0 )
+			 {
+				int i;
+				for( i = 0;  i < length;  i++ )
+					fsd_free( list[i] );
+				fsd_free( list );
+			 }
+			else
+				fsd_free_vector( list );
+		 }
+		fsd_exc_reraise();
+	 }
+	END_TRY
+	return self;
+}
+
+fsd_iter_t *
+fsd_iter_new( char **list, int length )
+{
+	return fsd_iter_new_impl( list, length, true );
+}
+
+fsd_iter_t *
+fsd_iter_new_const( const char *const *list, int length )
+{
+	return fsd_iter_new_impl( (char**)list, length, false );
+}
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/exception.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/exception.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/exception.h	(revision 77)
@@ -0,0 +1,257 @@
+/* $Id: exception.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ *  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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__EXCEPTION_H
+#define __DRMAA_UTILS__EXCEPTION_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <setjmp.h>
+
+#include <drmaa_utils/compat.h>
+
+#if defined(__GNUC__) && defined(DEBUGGING)
+extern int setjmp( jmp_buf __env )
+		__attribute__(( returns_twice ));
+#endif
+
+
+/** Exception type. */
+typedef struct fsd_exc_s fsd_exc_t;
+
+fsd_exc_t *
+fsd_exc_new( int code, char *message, bool own_message );
+
+/** Exception structure. */
+struct fsd_exc_s {
+	int (*code)( const fsd_exc_t* );
+	const char* (*message)( const fsd_exc_t* );
+	void (*destroy)( fsd_exc_t* );
+
+	int _code;
+	char *_message;
+	bool _own_message;
+	bool _own_self;
+};
+
+void
+fsd_exc_raise( fsd_exc_t *exc )
+		__attribute__(( noreturn ));
+
+void
+fsd_exc_raise_code( int error_code )
+		__attribute__(( noreturn ));
+
+void
+fsd_exc_raise_msg( int error_code, const char *message )
+		__attribute__(( noreturn ));
+
+void
+fsd_exc_raise_fmt( int error_code, const char *fmt, ... )
+		__attribute__(( noreturn, format( printf, 2, 3 ) ));
+
+void
+fsd_exc_raise_fmtv( int error_code, const char *fmt, va_list args )
+		__attribute__(( noreturn ));
+
+void
+fsd_exc_raise_sys( int errno_code )
+		__attribute__(( noreturn ));
+
+void
+fsd_exc_reraise(void)
+		__attribute__(( noreturn ));
+
+const fsd_exc_t *
+fsd_exc_get(void);
+
+void
+fsd_exc_clear(void);
+
+
+#define TRY \
+	 { \
+		fsd_exc_try_block_t* volatile _fsd_exc_try_block = NULL; \
+		int _fsd_exc_rc; \
+		_fsd_exc_try_block = fsd_exc_try( __FUNCTION__, __LINE__ ); \
+		if( _fsd_exc_try_block != NULL ) \
+			_fsd_exc_rc = setjmp( _fsd_exc_try_block->env ); \
+		else \
+			_fsd_exc_rc = FSD_ERRNO_EXC_END; \
+		while(1) \
+		 { \
+			bool _fsd_exc_handled = false; \
+			fsd_exc_control( _fsd_exc_try_block, &_fsd_exc_rc ); \
+			if( _fsd_exc_rc == FSD_ERRNO_EXC_END ) \
+				break; \
+			switch( _fsd_exc_rc ) \
+			 { \
+				case 0: {
+#define EXCEPT(error_code) \
+				 } break; \
+				case error_code: { \
+					_fsd_exc_handled = true;
+#define EXCEPT_DEFAULT \
+				 } break; \
+				default: \
+					if( _fsd_exc_rc > 0 ) \
+					 { \
+						_fsd_exc_handled = true;
+#define FINALLY \
+				 } break; \
+				case FSD_ERRNO_EXC_FINALLY: {
+#define ELSE \
+				 } break; \
+				case FSD_ERRNO_EXC_ELSE: {
+#define END_TRY \
+				 } break; \
+			 } \
+			if( _fsd_exc_handled ) \
+			 { \
+				fsd_assert( _fsd_exc_try_block->handled_exc != NULL ); \
+				_fsd_exc_try_block->handled_exc->destroy( \
+						_fsd_exc_try_block->handled_exc ); \
+				_fsd_exc_try_block->handled_exc = NULL; \
+			 } \
+		 } \
+	 }
+
+
+/** The state of exception handling block. */
+typedef enum {
+	FSD_EXC_ENTER, /**< Before try. */
+	FSD_EXC_TRY_BLOCK, /**< Insidie try-block. */
+	FSD_EXC_EXCEPTION_HANDLE, /**< Inside exception handling block. */
+	FSD_EXC_ELSE_BLOCK, /**< Inside else-block. */
+	FSD_EXC_FINALLY_BLOCK, /**< Inside finally block. */
+	FSD_EXC_LEAVE /**< Leaving try/except/finally block (after finally). */
+} fsd_exc_try_block_state_t;
+
+/**
+ * Try/except/else/finally block data structure.
+ * Holds the state for exception handling module.
+ *
+ * It also represents a point on the stack and other state of
+ * thread to wich it can be restored during "stack rollback"
+ * process after exception is raised.
+ */
+typedef struct fsd_exc_try_block_s {
+	jmp_buf env;  /**< Stack restore point for \c longjmp. */
+	fsd_exc_t *handled_exc; /**< Exception handled within block */
+	fsd_exc_try_block_state_t state;
+	const char *function; /**< Name of function */
+	int lineno; /**< Line number where try-block starts */
+} fsd_exc_try_block_t;
+
+
+fsd_exc_try_block_t *
+fsd_exc_try( const char *function, int lineno );
+
+void
+fsd_exc_control( fsd_exc_try_block_t *block, int *rc );
+
+
+const char *
+fsd_strerror( int error_code );
+
+/** Error codes. */
+typedef enum {
+	FSD_ERRNO_SUCCESS                    =  0,
+
+	FSD_ERRNO_EXC_ELSE                   = -1,
+	FSD_ERRNO_EXC_FINALLY                = -2,
+	FSD_ERRNO_EXC_END                    = -3,
+
+	/* _FSD_ERRNO_START = 1000, */
+
+	FSD_ERRNO_INTERNAL_ERROR             = 1001,
+	FSD_ERRNO_NO_MEMORY                  = 1002,
+	FSD_ERRNO_INVALID_ARGUMENT           = 1003,
+	FSD_ERRNO_INVALID_VALUE              = 1004,
+	FSD_ERRNO_INVALID_VALUE_FORMAT       = 1005,
+	FSD_ERRNO_STOP_ITERATION             = 1006,
+	FSD_ERRNO_NOT_IMPLEMENTED            = 1007,
+	FSD_ERRNO_NOT_INITIALIZED            = 1008,
+	FSD_ERRNO_TIMEOUT                    = 1009,
+	FSD_ERRNO_AUTH_FAILURE               = 1010,
+	FSD_ERRNO_AUTHZ_FAILURE              = 1011,
+	FSD_ERRNO_TRY_LATER                  = 1012,
+
+	FSD_ERRNO_DRM_COMMUNICATION_FAILURE  = 1013,
+	FSD_ERRNO_DRMS_INIT_FAILED           = 1014,
+	FSD_ERRNO_DRMS_EXIT_ERROR            = 1015,
+	FSD_ERRNO_DENIED_BY_DRM              = 1016,
+
+	/* DRMAA specific error codes: */
+	FSD_DRMAA_ERRNO_NO_ACTIVE_SESSION                    = 1032,
+	FSD_DRMAA_ERRNO_INVALID_CONTACT_STRING               = 1033,
+	FSD_DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR         = 1034,
+	FSD_DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED   = 1035,
+	FSD_DRMAA_ERRNO_ALREADY_ACTIVE_SESSION               = 1036,
+	FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT             = 1037,
+	FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE              = 1038,
+	FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES         = 1039,
+	FSD_DRMAA_ERRNO_INVALID_JOB                          = 1040,
+	FSD_DRMAA_ERRNO_RESUME_INCONSISTENT_STATE            = 1041,
+	FSD_DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE           = 1042,
+	FSD_DRMAA_ERRNO_HOLD_INCONSISTENT_STATE              = 1043,
+	FSD_DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE           = 1044,
+	FSD_DRMAA_ERRNO_EXIT_TIMEOUT                         = 1045,
+	FSD_DRMAA_ERRNO_NO_RUSAGE                            = 1046,
+
+	/* ARes specific error codes: */
+	FSD_ARES_ERRNO_INVALID_CONTACT_STRING                = 1052,
+	FSD_ARES_ERRNO_INVALID_ATTRIBUTE_FORMAT              = 1053,
+	FSD_ARES_ERRNO_INVALID_ATTRIBUTE_VALUE               = 1054,
+	FSD_ARES_ERRNO_CONFLICTING_ATTRIBUTE_VALUES          = 1055,
+	FSD_ARES_ERRNO_INVALID_ARES                          = 1056,
+
+	FSD_MIN_ERRNO = FSD_ERRNO_INTERNAL_ERROR,
+	FSD_MAX_ERRNO = FSD_ARES_ERRNO_INVALID_ARES
+} fsd_errno_t;
+
+
+#ifndef NDEBUG
+#	define fsd_assert( precondition ) \
+		do { \
+			if( ! (precondition) ) \
+				fsd_assertion_failed( __FILE__, __LINE__, \
+						__FUNCTION__, #precondition ); \
+		} while(0)
+#else
+#	define fsd_assert( precondition )  do{/* nothing */}while(0)
+#endif
+
+void
+fsd_assertion_failed( const char *file, int lineno,
+		const char *function, const char *precondition )
+		__attribute__(( noreturn ));
+
+void *
+fsd_exc_try_except(
+		void*(*f)(void*), void *data,
+		int *error_code,
+		char **error_message
+		);
+
+#endif /* __DRMAA_UTILS__EXCEPTION_H */
+
Index: /branches/2.0/drmaa2_utils/drmaa_utils/iter.h
===================================================================
--- /branches/2.0/drmaa2_utils/drmaa_utils/iter.h	(revision 77)
+++ /branches/2.0/drmaa2_utils/drmaa_utils/iter.h	(revision 77)
@@ -0,0 +1,49 @@
+/* $Id: iter.h 13 2011-04-20 15:41:43Z mmamonski $ */
+/*
+ *  PSNC DRMAA 2.0 utilities library
+ *  Copyright (C) 2012  Poznan Supercomputing and Networking Center
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __DRMAA_UTILS__ITER_H
+#define __DRMAA_UTILS__ITER_H
+
+#ifdef HAVE_CONFIG_H
+#	include <config.h>
+#endif
+
+#include <drmaa_utils/common.h>
+
+fsd_iter_t *
+fsd_iter_new( char **list, int length );
+
+fsd_iter_t *
+fsd_iter_new_const( const char *const *list, int length );
+
+struct fsd_iter_s {
+	const char* (*next)( fsd_iter_t *self );
+	void (*reset)( fsd_iter_t *self );
+	int (*len)( fsd_iter_t *self );
+	void (*append)( fsd_iter_t *self, char *string );
+	void (*destroy)( fsd_iter_t *self );
+	
+	char **_list;
+	int _position;
+	int _length;
+	bool _own_list;
+};
+
+#endif /* __DRMAA_UTILS__ITER_H */
+
Index: /branches/2.0/configure.ac
===================================================================
--- /branches/2.0/configure.ac	(revision 12)
+++ /branches/2.0/configure.ac	(revision 77)
@@ -1,9 +1,8 @@
-AC_INIT([DRMAA for PBS Pro], [1.0.7], [mamonski@man.poznan.pl], [pbs-drmaa])
+AC_INIT([DRMAA for Torque/PBS Pro], [2.0.0], [mamonski@man.poznan.pl], [pbs-drmaa2])
 AC_PREREQ(2.59)
 AC_REVISION([$Id$])
 AC_COPYRIGHT([
 DRMAA for Torque/PBS Professional
-Copyright (C) 2006-2009  FedStage Systems
-Copyright (C) 2011  Poznan Supercomputing and Networking Center
+Copyright (C) 2012  Poznan Supercomputing and Networking Center
 
 This program is free software: you can redistribute it and/or modify
@@ -21,8 +20,8 @@
 ])
 
-PBS_DRMAA_MAJOR=1
+PBS_DRMAA_MAJOR=2
 PBS_DRMAA_MINOR=0
-PBS_DRMAA_MICRO=7
-PBS_DRMAA_VERSION_INFO=1:7:0
+PBS_DRMAA_MICRO=0
+PBS_DRMAA_VERSION_INFO=2:0:0
 AC_SUBST([PBS_DRMAA_MAJOR])
 AC_SUBST([PBS_DRMAA_MINOR])
@@ -171,5 +170,5 @@
 ])
 AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_SUBDIRS([drmaa_utils])
+AC_CONFIG_SUBDIRS([drmaa2_utils])
 AC_OUTPUT
 
Index: /branches/2.0/Makefile.am
===================================================================
--- /branches/2.0/Makefile.am	(revision 12)
+++ /branches/2.0/Makefile.am	(revision 77)
@@ -24,3 +24,3 @@
  m4/missing-dev-prog.sh
 
-SUBDIRS = drmaa_utils pbs_drmaa
+SUBDIRS = drmaa2_utils pbs_drmaa
