text:
/** @file reducer_opadd.h
 *
 *  @brief Defines classes for doing parallel addition reductions.
 *
 *  @ingroup ReducersAdd
 *
 *  @see ReducersAdd
 */

#ifndef REDUCER_OPADD_H_INCLUDED
#define REDUCER_OPADD_H_INCLUDED

#include <cilk/reducer.h>

/** @defgroup ReducersAdd Addition Reducers
 *
 *  Addition reducers allow the computation of the sum of a set of values in
 *  parallel.
 *
 *  @ingroup Reducers
 *
 *  You should be familiar with @ref pagereducers "Cilk reducers", described in
 *  file `reducers.md`, and particularly with @ref reducers_using, before trying
 *  to use the information in this file.
 *
 *  @section redopadd_usage Usage Example
 *
 *      cilk::reducer< cilk::op_add<int> > r;
 *      cilk_for (int i = 0; i != N; ++i) {
 *          *r += a[i];
 *      }
 *      return r.get_value();
 *
 *  @section redopadd_monoid The Monoid
 *
 *  @subsection redopadd_monoid_values Value Set
 *
 *  The value set of an addition reducer is the set of values of `Type`, which
 *  is expected to be a builtin numeric type (or something like it, such as
 *  `std::complex`).
 *
 *  @subsection redopadd_monoid_operator Operator
 *
 *  The operator of an addition reducer is the addition operator, defined by
 *  the "`+`" binary operator on `Type`.
 *
 *  @subsection redopadd_monoid_identity Identity
 *
 *  The identity value of the reducer is the numeric value "`0`". This is
 *  expected to be the value of the default constructor `Type()`.
 *
 *  @section redopadd_operations Operations
 *
 *  @subsection redopadd_constructors Constructors
 *
 *      reducer()   // identity
 *      reducer(const Type& value)
 *      reducer(move_in(Type& variable))
 *
 *  @subsection redopadd_get_set Set and Get
 *
 *      r.set_value(const Type& value)
 *      const Type& = r.get_value() const
 *      r.move_in(Type& variable)
 *      r.move_out(Type& variable)
 *
 *  @subsection redopadd_initial Initial Values
 *
 *  If an addition reducer is constructed without an explicit initial value,
 *  then its initial value will be its identity value, as long as `Type`
 *  satisfies the requirements of @ref redopadd_types.
 *
 *  @subsection redopadd_view_ops View Operations
 *
 *      *r += a
 *      *r -= a
 *      ++*r
 *      --*r
 *      (*r)++
 *      (*r)--
 *      *r = *r + a
 *      *r = *r - a
 *      *r = *r ± a1 ± a2 … ± an
 *
 *  The post-increment and post-decrement operations do not return a value. (If
 *  they did, they would expose the value contained in the view, which is
 *  non-deterministic in the middle of a reduction.)
 *
 *  Note that subtraction operations are allowed on an addition reducer because
 *  subtraction is equivalent to addition with a negated operand. It is true
 *  that `(x - y) - z` is not equivalent to `x - (y - z)`, but
 *  `(x + (-y)) + (-z)` _is_ equivalent to `x + ((-y) + (-z))`.
 *
 *  @section redopadd_floating_point Issues with Floating-Point Types
 *
 *  Because of precision and round-off issues, floating-point addition is not
 *  really associative. For example, `(1e30 + -1e30) + 1 == 1`, but
 *  `1e30 + (-1e30 + 1) == 0`.
 *
 *  In many cases, this won't matter, but computations which have been
 *  carefully ordered to control round-off errors may not deal well with
 *  being reassociated. In general, you should be sure to understand the
 *  floating-point behavior of your program before doing any transformation
 *  that will reassociate its computations.
 *
 *  @section redopadd_types Type and Operator Requirements
 *
 *  `Type` must be `Copy Constructible`, `Default Constructible`, and
 *  `Assignable`.
 *
 *  The operator "`+=`" must be defined on `Type`, with `x += a` having the
 *  same meaning as `x = x + a`. In addition, if the code uses the "`-=`",
 *  pre-increment, post-increment, pre-decrement, or post-decrement operators,
 *  then the corresponding operators must be defined on `Type`.
 *
 *  The expression `Type()` must be a valid expression which yields the
 *  identity value (the value of `Type` whose numeric value is zero).
 *
 *  @section redopadd_in_c Addition Reducers in C
 *
 *  The @ref CILK_C_REDUCER_OPADD and @ref CILK_C_REDUCER_OPADD_TYPE macros can
 *  be used to do addition reductions in C. For example:
 *
 *      CILK_C_REDUCER_OPADD(r, double, 0);
 *      CILK_C_REGISTER_REDUCER(r);
 *      cilk_for(int i = 0; i != n; ++i) {
 *          REDUCER_VIEW(r) += a[i];
 *      }
 *      CILK_C_UNREGISTER_REDUCER(r);
 *      printf("The sum of the elements of a is %f\n", REDUCER_VIEW(r));
 *
 *  See @ref reducers_c_predefined.
 */

#ifdef __cplusplus

namespace cilk {

/** The addition reducer view class.
 *
 *  This is the view class for reducers created with
 *  `cilk::reducer< cilk::op_add<Type> >`. It holds the accumulator variable
 *  for the reduction, and allows only addition and subtraction operations to
 *  be performed on it.
 *
 *  @note   The reducer "dereference" operation (`reducer::operator *()`)
 *          yields a reference to the view. Thus, for example, the view class's
 *          `+=` operation would be used in an expression like `*r += a`, where
 *          `r` is an op_add reducer variable.
 *
 *  @tparam Type    The type of the contained accumulator variable. This will
 *                  be the value type of a monoid_with_view that is
 *                  instantiated with this view.
 *
 *  @see ReducersAdd
 *  @see op_add
 *
 *  @ingroup ReducersAdd
 */
template <typename Type>
class op_add_view : public scalar_view<Type>
{
    typedef scalar_view<Type> base;

public:
    /** Class to represent the right-hand side of
     *  `*reducer = *reducer ± value`.
     *
     *  The only assignment operator for the op_add_view class takes an
     *  rhs_proxy as its operand. This results in the syntactic restriction
     *  that the only expressions that can be assigned to an op_add_view are
     *  ones which generate an rhs_proxy — that is, expressions of the form
     *  `op_add_view ± value ... ± value`.
     *
     *  @warning
     *  The lhs and rhs views in such an assignment must be the same;
     *  otherwise, the behavior will be undefined. (I.e., `v1 = v1 + x` is
     *  legal; `v1 = v2 + x` is illegal.) This condition will be checked with a
     *  runtime assertion when compiled in debug mode.
     *
     *  @see op_add_view
     */
    class rhs_proxy {
        friend class op_add_view;

        const op_add_view* m_view;
        Type               m_value;

        // Constructor is invoked only from op_add_view::operator+() and
        // op_add_view::operator-().
        //
        rhs_proxy(const op_add_view* view, const Type& value) :
            m_view(view), m_value(value) {}

        rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
        rhs_proxy();                            // Disable default constructor

    public:
        //@{
        /** Add or subtract an additional rhs value. If `v` is an op_add_view
         *  and `a1` is a value, then the expression `v + a1` invokes the view's
         *  `operator+()` to create an rhs_proxy for `(v, a1)`; then
         *  `v + a1 + a2` invokes the rhs_proxy's `operator+()` to create a new
         *  rhs_proxy for `(v, a1+a2)`. This allows the right-hand side of an
         *  assignment to be not just `view ± value`, but
         *  `view ± value ± value ... ± value`. The effect is that
         *
         *      v = v ± a1 ± a2 ... ± an;
         *
         *  is evaluated as
         *
         *      v = v ± (±a1 ± a2 ... ± an);
         */
        rhs_proxy& operator+(const Type& x) { m_value += x; return *this; }
        rhs_proxy& operator-(const Type& x) { m_value -= x; return *this; }
        //@}
    };

    /** Default/identity constructor. This constructor initializes the
     *  contained value to `Type()`, which is expected to be the identity value
     *  for addition on `Type`.
     */
    op_add_view() : base() {}

    /** Construct with a specified initial value.
     */
    explicit op_add_view(const Type& v) : base(v) {}

    /** Reduction operation.
     *
     *  This function is invoked by the @ref op_add monoid to combine the views
     *  of two strands when the right strand merges with the left one. It adds
     *  the value contained in the right-strand view to the value contained in
     *  the left-strand view, and leaves the value in the right-strand view
     *  undefined.
     *
     *  @param  right   A pointer to the right-strand view. (`this` points to
     *                  the left-strand view.)
     *
     *  @note   Used only by the @ref op_add monoid to implement the monoid
     *          reduce operation.
     */
    void reduce(op_add_view* right) { this->m_value += right->m_value; }

    /** @name Accumulator variable updates.
     *
     *  These functions support the various syntaxes for incrementing or
     *  decrementing the accumulator variable contained in the view.
     */
    //@{

    /** Increment the accumulator variable by @a x.
     */
    op_add_view& operator+=(const Type& x) { this->m_value += x; return *this; }

    /** Decrement the accumulator variable by @a x.
     */
    op_add_view& operator-=(const Type& x) { this->m_value -= x; return *this; }

    /** Pre-increment.
     */
    op_add_view& operator++() { ++this->m_value; return *this; }

    /** Post-increment.
     *
     *  @note   Conventionally, post-increment operators return the old value
     *          of the incremented variable. However, reducer views do not
     *          expose their contained values, so `view++` does not have a
     *          return value.
     */
    void operator++(int) { this->m_value++; }

    /** Pre-decrement.
     */
    op_add_view& operator--() { --this->m_value; return *this; }

    /** Post-decrement.
     *
     *  @note   Conventionally, post-decrement operators return the old value
     *          of the decremented variable. However, reducer views do not
     *          expose their contained values, so `view--` does not have a
     *          return value.
     */
    void operator--(int) { this->m_value--; }

    /** Create an object representing `*this + x`.
     *
     *  @see rhs_proxy
     */
    rhs_proxy operator+(const Type& x) const { return rhs_proxy(this, x); }

    /** Create an object representing `*this - x`.
     *
     *  @see rhs_proxy
     */
    rhs_proxy operator-(const Type& x) const { return rhs_proxy(this, -x); }

    /** Assign the result of a `view ± value` expression to the view. Note that
     *  this is the only assignment operator for this class.
     *
     *  @see rhs_proxy
     */
    op_add_view& operator=(const rhs_proxy& rhs) {
        __CILKRTS_ASSERT(this == rhs.m_view);
        this->m_value += rhs.m_value;
        return *this;
    }

    //@}
};

/** Monoid class for addition reductions. Instantiate the cilk::reducer
 *  template class with an op_add monoid to create an addition reducer class.
 *  For example, to compute
 *  the sum of a set of `int` values:
 *
 *      cilk::reducer< cilk::op_add<int> > r;
 *
 *  @tparam Type    The reducer value type.
 *  @tparam Align   If `false` (the default), reducers instantiated on this
 *                  monoid will be naturally aligned (the Cilk library 1.0
 *                  behavior). If `true`, reducers instantiated on this monoid
 *                  will be cache-aligned for binary compatibility with
 *                  reducers in Cilk library version 0.9.
 *
 *  @see ReducersAdd
 *  @see op_add_view
 *
 *  @ingroup ReducersAdd
 */
template <typename Type, bool Align = false>
struct op_add : public monoid_with_view<op_add_view<Type>, Align> {};

/** **Deprecated** addition reducer wrapper class.
 *
 *  reducer_opadd is the same as @ref reducer<@ref op_add>, except that
 *  reducer_opadd is a proxy for the contained view, so that accumulator
 *  variable update operations can be applied directly to the reducer. For
 *  example, a value is added to a `reducer<%op_add>` with `*r += a`, but a
 *  value can be added to a `%reducer_opadd` with `r += a`.
 *
 *  @deprecated Users are strongly encouraged to use `reducer<monoid>`
 *              reducers rather than the old wrappers like reducer_opadd.
 *              The `reducer<monoid>` reducers show the reducer/monoid/view
 *              architecture more clearly, are more consistent in their
 *              implementation, and present a simpler model for new
 *              user-implemented reducers.
 *
 *  @note   Implicit conversions are provided between `%reducer_opadd`
 *          and `reducer<%op_add>`. This allows incremental code
 *          conversion: old code that used `%reducer_opadd` can pass a
 *          `%reducer_opadd` to a converted function that now expects a
 *          pointer or reference to a `reducer<%op_add>`, and vice
 *          versa.
 *
 *  @tparam Type    The value type of the reducer.
 *
 *  @see op_add
 *  @see reducer
 *  @see ReducersAdd
 *
 *  @ingroup ReducersAdd
 */
template <typename Type>
class reducer_opadd : public reducer< op_add<Type, true> >
{
    typedef reducer< op_add<Type, true> > base;
    using base::view;

  public:
    /// The view type for the reducer.
    typedef typename base::view_type        view_type;

    /// The view's rhs proxy type.
    typedef typename view_type::rhs_proxy   rhs_proxy;

    /// The view type for the reducer.
    typedef view_type                       View;

    /// The monoid type for the reducer.
    typedef typename base::monoid_type      Monoid;

    /** @name Constructors
     */
    //@{

    /** Default (identity) constructor.
     *
     * Constructs the wrapper with the default initial value of `Type()`.
     */
    reducer_opadd() {}

    /** Value constructor.
     *
     *  Constructs the wrapper with a specified initial value.
     */
    explicit reducer_opadd(const Type& initial_value) : base(initial_value) {}

    //@}

    /** @name Forwarded functions
     *  @details Functions that update the contained accumulator variable are
     *  simply forwarded to the contained @ref op_add_view. */
    //@{

    /// @copydoc op_add_view::operator+=(const Type&)
    reducer_opadd& operator+=(const Type& x)    { view() += x; return *this; }

    /// @copydoc op_add_view::operator-=(const Type&)
    reducer_opadd& operator-=(const Type& x)    { view() -= x; return *this; }

    /// @copydoc op_add_view::operator++()
    reducer_opadd& operator++()                 { ++view(); return *this; }

    /// @copydoc op_add_view::operator++(int)
    void operator++(int)                        { view()++; }

    /// @copydoc op_add_view::operator-\-()
    reducer_opadd& operator--()                 { --view(); return *this; }

    /// @copydoc op_add_view::operator-\-(int)
    void operator--(int)                        { view()--; }

    // The legacy definitions of reducer_opadd::operator+() and
    // reducer_opadd::operator-() have different behavior and a different
    // return type than this definition. The legacy version is defined as a
    // member function, so this new version is defined as a free function to
    // give it a different signature, so that they won't end up sharing a
    // single object file entry.

    /// @copydoc op_add_view::operator+(const Type&) const
    friend rhs_proxy operator+(const reducer_opadd& r, const Type& x)
    {
        return r.view() + x;
    }
    /// @copydoc op_add_view::operator-(const Type&) const
    friend rhs_proxy operator-(const reducer_opadd& r, const Type& x)
    {
        return r.view() - x;
    }
    /// @copydoc op_add_view::operator=(const rhs_proxy&)
    reducer_opadd& operator=(const rhs_proxy& temp)
    {
        view() = temp;
        return *this;
    }
    //@}

    /** @name Dereference
     *  @details Dereferencing a wrapper is a no-op. It simply returns the
     *  wrapper. Combined with the rule that the wrapper forwards view
     *  operations to its contained view, this means that view operations can
     *  be written the same way on reducers and wrappers, which is convenient
     *  for incrementally converting old code using wrappers to use reducers
     *  instead. That is:
     *
     *      reducer< op_add<int> > r;
     *      *r += a;    // *r returns the view
     *                  // operator += is a view member function
     *
     *      reducer_opadd<int> w;
     *      *w += a;    // *w returns the wrapper
     *                  // operator += is a wrapper member function that
     *                  // calls the corresponding view function
     */
    //@{
    reducer_opadd&       operator*()       { return *this; }
    reducer_opadd const& operator*() const { return *this; }

    reducer_opadd*       operator->()       { return this; }
    reducer_opadd const* operator->() const { return this; }
    //@}

    /** @name Upcast
     *  @details In Cilk library 0.9, reducers were always cache-aligned. In
     *  library  1.0, reducer cache alignment is optional. By default, reducers
     *  are unaligned (i.e., just naturally aligned), but legacy wrappers
     *  inherit from cache-aligned reducers for binary compatibility.
     *
     *  This means that a wrapper will automatically be upcast to its aligned
     *  reducer base class. The following conversion operators provide
     *  pseudo-upcasts to the corresponding unaligned reducer class.
     */
    //@{
    operator reducer< op_add<Type, false> >& ()
    {
        return *reinterpret_cast< reducer< op_add<Type, false> >* >(this);
    }
    operator const reducer< op_add<Type, false> >& () const
    {
        return *reinterpret_cast< const reducer< op_add<Type, false> >* >(this);
    }
    //@}
};

/// @cond internal
/** Metafunction specialization for reducer conversion.
 *
 *  This specialization of the @ref legacy_reducer_downcast template class
 *  defined in reducer.h causes the `reducer< op_add<Type> >` class to have an
 *  `operator reducer_opadd<Type>& ()` conversion operator that statically
 *  downcasts the `reducer<op_add>` to the corresponding `reducer_opadd` type.
 *  (The reverse conversion, from `reducer_opadd` to `reducer<op_add>`, is just
 *  an upcast, which is provided for free by the language.)
 *
 *  @ingroup ReducersAdd
 */
template <typename Type, bool Align>
struct legacy_reducer_downcast<reducer<op_add<Type, Align> > >
{
    typedef reducer_opadd<Type> type;
};
/// @endcond

} // namespace cilk

#endif // __cplusplus

/** @ingroup ReducersAdd
 */
//@{

/** @name C Language Reducer Macros
 *
 *  These macros are used to declare and work with numeric op_add reducers in
 *  C code.
 *
 *  @see @ref page_reducers_in_c
 */
 //@{

__CILKRTS_BEGIN_EXTERN_C

/** Opadd reducer type name.
 *
 *  This macro expands into the identifier which is the name of the op_add
 *  reducer type for a specified numeric type.
 *
 *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
 *              the type of the reducer.
 *
 *  @see @ref reducers_c_predefined
 *  @see ReducersAdd
 */
#define CILK_C_REDUCER_OPADD_TYPE(tn)                                         \
    __CILKRTS_MKIDENT(cilk_c_reducer_opadd_,tn)

/** Declare an op_add reducer object.
 *
 *  This macro expands into a declaration of an op_add reducer object for a
 *  specified numeric type. For example:
 *
 *      CILK_C_REDUCER_OPADD(my_reducer, double, 0.0);
 *
 *  @param  obj The variable name to be used for the declared reducer object.
 *  @param  tn  The @ref reducers_c_type_names "numeric type name" specifying
 *              the type of the reducer.
 *  @param  v   The initial value for the reducer. (A value which can be
 *              assigned to the numeric type represented by @a tn.)
 *
 *  @see @ref reducers_c_predefined
 *  @see ReducersAdd
 */
#define CILK_C_REDUCER_OPADD(obj,tn,v)                                        \
    CILK_C_REDUCER_OPADD_TYPE(tn) obj =                                       \
        CILK_C_INIT_REDUCER(_Typeof(obj.value),                               \
                        __CILKRTS_MKIDENT(cilk_c_reducer_opadd_reduce_,tn),   \
                        __CILKRTS_MKIDENT(cilk_c_reducer_opadd_identity_,tn), \
                        __cilkrts_hyperobject_noop_destroy, v)

/// @cond internal

/** Declare the op_add reducer functions for a numeric type.
 *
 *  This macro expands into external function declarations for functions which
 *  implement the reducer functionality for the op_add reducer type for a
 *  specified numeric type.
 *
 *  @param  t   The value type of the reducer.
 *  @param  tn  The value "type name" identifier, used to construct the reducer
 *              type name, function names, etc.
 */
#define CILK_C_REDUCER_OPADD_DECLARATION(t,tn)                             \
    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPADD_TYPE(tn);       \
    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opadd,tn,l,r);         \
    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn);

/** Define the op_add reducer functions for a numeric type.
 *
 *  This macro expands into function definitions for functions which implement
 *  the reducer functionality for the op_add reducer type for a specified
 *  numeric type.
 *
 *  @param  t   The value type of the reducer.
 *  @param  tn  The value "type name" identifier, used to construct the reducer
 *              type name, function names, etc.
 */
#define CILK_C_REDUCER_OPADD_DEFINITION(t,tn)                              \
    typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPADD_TYPE(tn);       \
    __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opadd,tn,l,r)          \
        { *(t*)l += *(t*)r; }                                              \
    __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn)            \
        { *(t*)v = 0; }

//@{
/** @def CILK_C_REDUCER_OPADD_INSTANCE
 *  @brief Declare or define implementation functions for a reducer type.
 *
 *  In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
 *  will be defined, and this macro will generate reducer implementation
 *  functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined,
 *  and this macro will expand into external declarations for the functions.
 */
#ifdef CILK_C_DEFINE_REDUCERS
#   define CILK_C_REDUCER_OPADD_INSTANCE(t,tn)  \
        CILK_C_REDUCER_OPADD_DEFINITION(t,tn)
#else
#   define CILK_C_REDUCER_OPADD_INSTANCE(t,tn)  \
        CILK_C_REDUCER_OPADD_DECLARATION(t,tn)
#endif
//@}

/*  Declare or define an instance of the reducer type and its functions for each
 *  numeric type.
 */
CILK_C_REDUCER_OPADD_INSTANCE(char,                 char)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned char,        uchar)
CILK_C_REDUCER_OPADD_INSTANCE(signed char,          schar)
CILK_C_REDUCER_OPADD_INSTANCE(wchar_t,              wchar_t)
CILK_C_REDUCER_OPADD_INSTANCE(short,                short)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned short,       ushort)
CILK_C_REDUCER_OPADD_INSTANCE(int,                  int)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned int,         uint)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned int,         unsigned) /* alternate name */
CILK_C_REDUCER_OPADD_INSTANCE(long,                 long)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned long,        ulong)
CILK_C_REDUCER_OPADD_INSTANCE(long long,            longlong)
CILK_C_REDUCER_OPADD_INSTANCE(unsigned long long,   ulonglong)
CILK_C_REDUCER_OPADD_INSTANCE(float,                float)
CILK_C_REDUCER_OPADD_INSTANCE(double,               double)
CILK_C_REDUCER_OPADD_INSTANCE(long double,          longdouble)

//@endcond

__CILKRTS_END_EXTERN_C

//@}

//@}

#endif /*  REDUCER_OPADD_H_INCLUDED */


text:
[![Build Status](https://travis-ci.org/boxen/puppet-gcc.png?branch=master)](https://travis-ci.org/boxen/puppet-gcc)

## Usage

```puppet
include gcc
```

## Required Puppet Modules

* `boxen`
* `homebrew`
* `stdlib`

redpajama_set_name: RedPajamaGithub


text:
import errno
import os
import signal
import time
from contextlib import closing

import psutil
from twitter.common import log
from twitter.common.dirutil import lock_file, safe_mkdir
from twitter.common.quantity import Amount, Time
from twitter.common.recordio import ThriftRecordWriter

from apache.thermos.common.ckpt import CheckpointDispatcher
from apache.thermos.common.path import TaskPath

from gen.apache.thermos.ttypes import ProcessState, ProcessStatus, RunnerCkpt, TaskState, TaskStatus

class TaskKiller(object):
  """
    Task killing interface.
  """

  def __init__(self, task_id, checkpoint_root):
    self._task_id = task_id
    self._checkpoint_root = checkpoint_root

  def kill(self, force=True):
    TaskRunnerHelper.kill(self._task_id, self._checkpoint_root, force=force,
                          terminal_status=TaskState.KILLED)

  def lose(self, force=True):
    TaskRunnerHelper.kill(self._task_id, self._checkpoint_root, force=force,
                          terminal_status=TaskState.LOST)

class TaskRunnerHelper(object):
  """
    TaskRunner helper methods that can be operated directly upon checkpoint
    state.  These operations do not require knowledge of the underlying
    task.

    TaskRunnerHelper is sort of a mishmash of "checkpoint-only" operations and
    the "Process Platform" stuff that started to get pulled into process.py

    This really needs some hard design thought to see if it can be extracted out
    even further.
  """
  class Error(Exception): pass
  class PermissionError(Error): pass

  # Maximum drift between when the system says a task was forked and when we checkpointed
  # its fork_time (used as a heuristic to determine a forked task is really ours instead of
  # a task with coincidentally the same PID but just wrapped around.)
  MAX_START_TIME_DRIFT = Amount(10, Time.SECONDS)

  @staticmethod
  def get_actual_user():
    import getpass, pwd
    try:
      pwd_entry = pwd.getpwuid(os.getuid())
    except KeyError:
      return getpass.getuser()
    return pwd_entry[0]

  @staticmethod
  def process_from_name(task, process_name):
    if task.has_processes():
      for process in task.processes():
        if process.name().get() == process_name:
          return process
    return None

  @classmethod
  def this_is_really_our_pid(cls, process, current_user, start_time):
    """
      A heuristic to make sure that this is likely the pid that we own/forked.  Necessary
      because of pid-space wrapping.  We don't want to go and kill processes we don't own,
      especially if the killer is running as root.

      process: psutil.Process representing the process to check
      current_user: user expected to own the process
      start_time: time at which it's expected the process has started

      Raises:
        psutil.NoSuchProcess - if the Process supplied no longer exists
    """
    if process.username != current_user:
      log.info("Expected pid %s to be ours but the pid user is %s and we're %s" % (
        process.pid, process.username, current_user))
      return False

    if abs(start_time - process.create_time) >= cls.MAX_START_TIME_DRIFT.as_(Time.SECONDS):
      log.info("Expected pid %s start time to be %s but it's %s" % (
        process.pid, start_time, process.create_time))
      return False

    return True

  @classmethod
  def scan_process(cls, state, process_name):
    """
      Given a RunnerState and a process_name, return the following:
        (coordinator pid, process pid, process tree)
        (int or None, int or None, set)

    """
    process_run = state.processes[process_name][-1]
    process_owner = state.header.user

    coordinator_pid, pid, tree = None, None, set()

    if process_run.coordinator_pid:
      try:
        coordinator_process = psutil.Process(process_run.coordinator_pid)
        if cls.this_is_really_our_pid(coordinator_process, process_owner, process_run.fork_time):
          coordinator_pid = process_run.coordinator_pid
      except psutil.NoSuchProcess:
        log.info('  Coordinator %s [pid: %s] completed.' % (process_run.process,
            process_run.coordinator_pid))
      except psutil.Error as err:
        log.warning('  Error gathering information on pid %s: %s' % (process_run.coordinator_pid,
            err))

    if process_run.pid:
      try:
        process = psutil.Process(process_run.pid)
        if cls.this_is_really_our_pid(process, process_owner, process_run.start_time):
          pid = process.pid
      except psutil.NoSuchProcess:
        log.info('  Process %s [pid: %s] completed.' % (process_run.process, process_run.pid))
      except psutil.Error as err:
        log.warning('  Error gathering information on pid %s: %s' % (process_run.pid, err))
      else:
        if pid:
          try:
            tree = set(proc.pid for proc in process.get_children(recursive=True))
          except psutil.Error:
            log.warning('  Error gathering information on children of pid %s' % pid)

    return (coordinator_pid, pid, tree)

  @classmethod
  def scantree(cls, state):
    """
      Scan the process tree associated with the provided task state.

      Returns a dictionary of process name => (coordinator pid, pid, pid children)
      If the coordinator is no longer active, coordinator pid will be None.  If the
      forked process is no longer active, pid will be None and its children will be
      an empty set.
    """
    return dict((process_name, cls.scan_process(state, process_name))
                for process_name in state.processes)

  @classmethod
  def safe_signal(cls, pid, sig=signal.SIGTERM):
    try:
      os.kill(pid, sig)
    except OSError as e:
      if e.errno not in (errno.ESRCH, errno.EPERM):
        log.error('Unexpected error in os.kill: %s' % e)
    except Exception as e:
      log.error('Unexpected error in os.kill: %s' % e)

  @classmethod
  def terminate_pid(cls, pid):
    cls.safe_signal(pid, signal.SIGTERM)

  @classmethod
  def kill_pid(cls, pid):
    cls.safe_signal(pid, signal.SIGKILL)

  @classmethod
  def kill_group(cls, pgrp):
    cls.safe_signal(-pgrp, signal.SIGKILL)

  @classmethod
  def _get_process_tuple(cls, state, process_name):
    assert process_name in state.processes and len(state.processes[process_name]) > 0
    return cls.scan_process(state, process_name)

  @classmethod
  def _get_coordinator_group(cls, state, process_name):
    assert process_name in state.processes and len(state.processes[process_name]) > 0
    return state.processes[process_name][-1].coordinator_pid

  @classmethod
  def terminate_process(cls, state, process_name):
    log.debug('TaskRunnerHelper.terminate_process(%s)' % process_name)
    _, pid, _ = cls._get_process_tuple(state, process_name)
    if pid:
      log.debug('   => SIGTERM pid %s' % pid)
      cls.terminate_pid(pid)
    return bool(pid)

  @classmethod
  def kill_process(cls, state, process_name):
    log.debug('TaskRunnerHelper.kill_process(%s)' % process_name)
    coordinator_pgid = cls._get_coordinator_group(state, process_name)
    coordinator_pid, pid, tree = cls._get_process_tuple(state, process_name)
    # This is super dangerous.  TODO(wickman)  Add a heuristic that determines
    # that 1) there are processes that currently belong to this process group
    #  and 2) those processes have inherited the coordinator checkpoint filehandle
    # This way we validate that it is in fact the process group we expect.
    if coordinator_pgid:
      log.debug('   => SIGKILL coordinator group %s' % coordinator_pgid)
      cls.kill_group(coordinator_pgid)
    if coordinator_pid:
      log.debug('   => SIGKILL coordinator %s' % coordinator_pid)
      cls.kill_pid(coordinator_pid)
    if pid:
      log.debug('   => SIGKILL pid %s' % pid)
      cls.kill_pid(pid)
    for child in tree:
      log.debug('   => SIGKILL child %s' % child)
      cls.kill_pid(child)
    return bool(coordinator_pid or pid or tree)

  @classmethod
  def kill_runner(cls, state):
    log.debug('TaskRunnerHelper.kill_runner()')
    if not state or not state.statuses:
      raise cls.Error('Could not read state!')
    pid = state.statuses[-1].runner_pid
    if pid == os.getpid():
      raise cls.Error('Unwilling to commit seppuku.')
    try:
      os.kill(pid, signal.SIGKILL)
      return True
    except OSError as e:
      if e.errno == errno.EPERM:
        # Permission denied
        return False
      elif e.errno == errno.ESRCH:
        # pid no longer exists
        return True
      raise

  @classmethod
  def open_checkpoint(cls, filename, force=False, state=None):
    """
      Acquire a locked checkpoint stream.
    """
    safe_mkdir(os.path.dirname(filename))
    fp = lock_file(filename, "a+")
    if fp in (None, False):
      if force:
        log.info('Found existing runner, forcing leadership forfeit.')
        state = state or CheckpointDispatcher.from_file(filename)
        if cls.kill_runner(state):
          log.info('Successfully killed leader.')
          # TODO(wickman)  Blocking may not be the best idea here.  Perhaps block up to
          # a maximum timeout.  But blocking is necessary because os.kill does not immediately
          # release the lock if we're in force mode.
          fp = lock_file(filename, "a+", blocking=True)
      else:
        log.error('Found existing runner, cannot take control.')
    if fp in (None, False):
      raise cls.PermissionError('Could not open locked checkpoint: %s, lock_file = %s' %
        (filename, fp))
    ckpt = ThriftRecordWriter(fp)
    ckpt.set_sync(True)
    return ckpt

  @classmethod
  def kill(cls, task_id, checkpoint_root, force=False,
           terminal_status=TaskState.KILLED, clock=time):
    """
      An implementation of Task killing that doesn't require a fully hydrated TaskRunner object.
      Terminal status must be either KILLED or LOST state.
    """
    if terminal_status not in (TaskState.KILLED, TaskState.LOST):
      raise cls.Error('terminal_status must be KILLED or LOST (got %s)' %
                      TaskState._VALUES_TO_NAMES.get(terminal_status) or terminal_status)
    pathspec = TaskPath(root=checkpoint_root, task_id=task_id)
    checkpoint = pathspec.getpath('runner_checkpoint')
    state = CheckpointDispatcher.from_file(checkpoint)

    if state is None or state.header is None or state.statuses is None:
      if force:
        log.error('Task has uninitialized TaskState - forcibly finalizing')
        cls.finalize_task(pathspec)
        return
      else:
        log.error('Cannot update states in uninitialized TaskState!')
        return

    ckpt = cls.open_checkpoint(checkpoint, force=force, state=state)

    def write_task_state(state):
      update = TaskStatus(state=state, timestamp_ms=int(clock.time() * 1000),
                          runner_pid=os.getpid(), runner_uid=os.getuid())
      ckpt.write(RunnerCkpt(task_status=update))

    def write_process_status(status):
      ckpt.write(RunnerCkpt(process_status=status))

    if cls.is_task_terminal(state.statuses[-1].state):
      log.info('Task is already in terminal state!  Finalizing.')
      cls.finalize_task(pathspec)
      return

    with closing(ckpt):
      write_task_state(TaskState.ACTIVE)
      for process, history in state.processes.items():
        process_status = history[-1]
        if not cls.is_process_terminal(process_status.state):
          if cls.kill_process(state, process):
            write_process_status(ProcessStatus(process=process,
              state=ProcessState.KILLED, seq=process_status.seq + 1, return_code=-9,
              stop_time=clock.time()))
          else:
            if process_status.state is not ProcessState.WAITING:
              write_process_status(ProcessStatus(process=process,
                state=ProcessState.LOST, seq=process_status.seq + 1))
      write_task_state(terminal_status)
    cls.finalize_task(pathspec)

  @classmethod
  def reap_children(cls):
    pids = set()

    while True:
      try:
        pid, status, rusage = os.wait3(os.WNOHANG)
        if pid == 0:
          break
        pids.add(pid)
        log.debug('Detected terminated process: pid=%s, status=%s, rusage=%s' % (
          pid, status, rusage))
      except OSError as e:
        if e.errno != errno.ECHILD:
          log.warning('Unexpected error when calling waitpid: %s' % e)
        break

    return pids

  TERMINAL_PROCESS_STATES = frozenset([
    ProcessState.SUCCESS,
    ProcessState.KILLED,
    ProcessState.FAILED,
    ProcessState.LOST])

  TERMINAL_TASK_STATES = frozenset([
    TaskState.SUCCESS,
    TaskState.FAILED,
    TaskState.KILLED,
    TaskState.LOST])

  @classmethod
  def is_process_terminal(cls, process_status):
    return process_status in cls.TERMINAL_PROCESS_STATES

  @classmethod
  def is_task_terminal(cls, task_status):
    return task_status in cls.TERMINAL_TASK_STATES

  @classmethod
  def initialize_task(cls, spec, task):
    active_task = spec.given(state='active').getpath('task_path')
    finished_task = spec.given(state='finished').getpath('task_path')
    is_active, is_finished = os.path.exists(active_task), os.path.exists(finished_task)
    if is_finished:
      raise cls.Error('Cannot initialize task with "finished" record!')
    if not is_active:
      safe_mkdir(os.path.dirname(active_task))
      with open(active_task, 'w') as fp:
        fp.write(task)

  @classmethod
  def finalize_task(cls, spec):
    active_task = spec.given(state='active').getpath('task_path')
    finished_task = spec.given(state='finished').getpath('task_path')
    is_active, is_finished = os.path.exists(active_task), os.path.exists(finished_task)
    if not is_active:
      raise cls.Error('Cannot finalize task with no "active" record!')
    elif is_finished:
      raise cls.Error('Cannot finalize task with "finished" record!')
    safe_mkdir(os.path.dirname(finished_task))
    os.rename(active_task, finished_task)
    os.utime(finished_task, None)


text:
package org.gradoop.common.model.impl.pojo;

import org.gradoop.common.model.api.entities.GraphHead;
import org.gradoop.common.model.impl.id.GradoopId;
import org.gradoop.common.model.impl.properties.Properties;
import org.gradoop.common.util.GradoopConstants;
import org.testng.annotations.Test;

import static org.testng.AssertJUnit.*;
import static org.testng.Assert.assertNotEquals;

public class GraphHeadTest {
  @Test
  public void createWithIDTest() {
    GradoopId graphID = GradoopId.get();
    GraphHead g = new EPGMGraphHeadFactory().initGraphHead(graphID);
    assertEquals(graphID, g.getId());
    assertEquals(0, g.getPropertyCount());
  }

  @Test
  public void createDefaultGraphTest() {
    GradoopId graphID = GradoopId.get();
    String label = "A";
    Properties props = Properties.create();
    props.set("k1", "v1");
    props.set("k2", "v2");

    GraphHead graphHead = new EPGMGraphHeadFactory().initGraphHead(graphID, label, props);

    assertEquals(graphID, graphHead.getId());
    assertEquals(label, graphHead.getLabel());
    assertEquals(2, graphHead.getPropertyCount());
    assertEquals("v1", graphHead.getPropertyValue("k1").getString());
    assertEquals("v2", graphHead.getPropertyValue("k2").getString());
  }

  @Test
  public void createWithMissingLabelTest() {
    GradoopId graphID = GradoopId.get();
    GraphHead g = new EPGMGraphHeadFactory().initGraphHead(graphID);
    assertEquals(GradoopConstants.DEFAULT_GRAPH_LABEL, g.getLabel());
  }

  @Test(expectedExceptions = NullPointerException.class)
  public void createWithNullIDTest() {
    new EPGMGraphHeadFactory().initGraphHead(null);
  }

  @Test(expectedExceptions = NullPointerException.class)
  public void createWithNullLabelTest() {
    GradoopId graphID = GradoopId.get();
    new EPGMGraphHeadFactory().initGraphHead(graphID, null);
  }

  @Test
  public void equalsTest() {
    GradoopId graphID1 = GradoopId.get();
    GradoopId graphID2 = GradoopId.get();

    GraphHead graphHead1 = new EPGMGraphHeadFactory().initGraphHead(graphID1);
    GraphHead graphHead2 = new EPGMGraphHeadFactory().initGraphHead(graphID1);
    GraphHead graphHead3 = new EPGMGraphHeadFactory().initGraphHead(graphID2);

    assertEquals("Graph heads were not equal", graphHead1, graphHead1);
    assertEquals("Graph heads were not equal", graphHead1, graphHead2);
    assertNotEquals(graphHead1, graphHead3, "Graph heads were equal");
  }

  @Test
  public void testHashCode() {
    GradoopId graphID1 = GradoopId.get();
    GradoopId graphID2 = GradoopId.get();

    GraphHead graphHead1 = new EPGMGraphHeadFactory().initGraphHead(graphID1);
    GraphHead graphHead2 = new EPGMGraphHeadFactory().initGraphHead(graphID1);
    GraphHead graphHead3 = new EPGMGraphHeadFactory().initGraphHead(graphID2);

    assertEquals("Graph heads have different hash", graphHead2.hashCode(), graphHead1.hashCode());
    assertFalse("Graph heads have same hash", graphHead1.hashCode() == graphHead3.hashCode());
  }

}


text: export default (thing: any) => !!(thing && thing.Window) && thing instanceof thing.Window


text:
package org.simplity.kernel.db;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Struct;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.simplity.kernel.ApplicationError;
import org.simplity.kernel.Tracer;
import org.simplity.kernel.data.DataSheet;
import org.simplity.kernel.data.DynamicSheet;
import org.simplity.kernel.data.FieldsInterface;
import org.simplity.kernel.data.MultiRowsSheet;
import org.simplity.kernel.value.IntegerValue;
import org.simplity.kernel.value.Value;
import org.simplity.kernel.value.ValueType;
import org.simplity.service.ServiceContext;

import oracle.jdbc.driver.OracleConnection;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

/**
 * We use DbDriver as a wrapper on JDBC to restrict the features to a smaller
 * subset that is easy to maintain.
 *
 * @author simplity.org
 *
 */
public class DbDriver {
	// static final int[] TEXT_TYPES = {Types.CHAR, Types.LONGNVARCHAR,
	// Types.LONGVARCHAR, Types.NCHAR, Types.NVARCHAR, Types.VARCHAR};

	/*
	 * for sql escaping
	 */
	private static final String OUR_ESCAPE_CHAR = "!";
	private static final String OUR_ESCAPE_STR = "!!";
	private static final String CONTEXT_PREFIX = "java:/comp/env/";

	/*
	 * we store sql types with corresponding value types
	 */
	private static final int[] LONG_TYPES = { Types.BIGINT, Types.INTEGER,
			Types.SMALLINT };
	private static final int[] DATE_TYPES = { Types.DATE, Types.TIME,
			Types.TIMESTAMP };
	private static final int[] DOUBLE_TYPES = { Types.DECIMAL, Types.DOUBLE,
			Types.FLOAT, Types.REAL };
	private static final int[] BOOLEAN_TYPES = { Types.BIT, Types.BOOLEAN };
	private static final Map<Integer, ValueType> SQL_TYPES = new HashMap<Integer, ValueType>();

	/**
	 * character used in like operator to match any characters
	 */
	public static final char LIKE_ANY = '%';
	/*
	 * meta 0-table columns, 1-primary keys, 2-procedure parameters. refer to
	 * meta.getColumnNames(), getPrimarykeys() and getProcedureColumns() of JDBC
	 */

	/*
	 * we are going to use value types s many time, it is ugly to use full name.
	 * Let us have some short and sweet names
	 */
	private static final ValueType INT = ValueType.INTEGER;
	private static final ValueType TXT = ValueType.TEXT;
	private static final ValueType BOOL = ValueType.BOOLEAN;

	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int TABLE_IDX = 0;
	private static final String[] TABLE_NAMES = { "schema", "tableName",
			"tableType", "remarks" };
	private static final ValueType[] TABLE_TYPES = { TXT, TXT, TXT, TXT };
	private static final int[] TABLE_POSNS = { 2, 3, 4, 5 };
	private static final String[] TABLE_TYPES_TO_EXTRACT = { "TABLE", "VIEW" };
	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int COL_IDX = 1;
	private static final String[] COL_NAMES = { "schema", "tableName",
			"columnName", "sqlType", "sqlTypeName", "size", "nbrDecimals",
			"remarks", "nullable" };
	private static final ValueType[] COL_TYPES = { TXT, TXT, TXT, INT, TXT, INT,
			INT, TXT, BOOL };
	private static final int[] COL_POSNS = { 2, 3, 4, 5, 6, 7, 9, 12, 18 };

	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int KEY_IDX = 2;
	private static final String[] KEY_NAMES = { "columnName", "sequence" };
	private static final ValueType[] KEY_TYPES = { TXT, INT };
	private static final int[] KEY_POSNS = { 4, 5 };

	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int PROC_IDX = 3;
	private static final String[] PROC_NAMES = { "schema", "procedureName",
			"procedureType", "remarks" };
	private static final ValueType[] PROC_TYPES = { TXT, TXT, INT, TXT };
	private static final int[] PROC_POSNS = { 2, 3, 8, 7 };

	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int PARAM_IDX = 4;
	private static final String[] PARAM_NAMES = { "schema", "procedureName",
			"paramName", "columnType", "sqlType", "sqlTypeName", "size",
			"precision", "scale", "remarks", "nullable", "position" };
	private static final ValueType[] PARAM_TYPES = { TXT, TXT, TXT, INT, INT,
			TXT, INT, INT, INT, TXT, BOOL, INT };
	private static final int[] PARAM_POSNS = { 2, 3, 4, 5, 6, 7, 9, 8, 10, 13,
			19, 18 };

	/*
	 * names, types and positions as per result set for meta.getUDTs()
	 */
	private static final int STRUCT_IDX = 5;
	private static final String[] STRUCT_NAMES = { "schema", "structName",
			"structType", "remarks" };
	private static final ValueType[] STRUCT_TYPES = { TXT, TXT, TXT, TXT };
	private static final int[] STRUCT_POSNS = { 2, 3, 5, 6 };
	private static final int[] STRUCT_TYPES_TO_EXTRACT = { Types.STRUCT };
	/*
	 * names, types and positions as per result set for meta.getTables()
	 */
	private static final int ATTR_IDX = 6;
	private static final String[] ATTR_NAMES = { "schema", "structName",
			"attributeName", "sqlType", "sqlTypeName", "size", "nbrDecimals",
			"remarks", "nullable", "position" };
	private static final ValueType[] ATTR_TYPES = { TXT, TXT, TXT, INT, TXT,
			INT, INT, TXT, BOOL, INT };
	private static final int[] ATTR_POSNS = { 2, 3, 4, 5, 6, 7, 8, 11, 17, 16 };

	/*
	 * put them into array for modularity
	 */
	private static final String[][] META_COLUMNS = { TABLE_NAMES, COL_NAMES,
			KEY_NAMES, PROC_NAMES, PARAM_NAMES, STRUCT_NAMES, ATTR_NAMES };
	private static final ValueType[][] META_TYPES = { TABLE_TYPES, COL_TYPES,
			KEY_TYPES, PROC_TYPES, PARAM_TYPES, STRUCT_TYPES, ATTR_TYPES };
	private static final int[][] META_POSNS = { TABLE_POSNS, COL_POSNS,
			KEY_POSNS, PROC_POSNS, PARAM_POSNS, STRUCT_POSNS, ATTR_POSNS };

	static {
		for (int i : LONG_TYPES) {
			SQL_TYPES.put(new Integer(i), ValueType.INTEGER);
		}
		for (int i : DATE_TYPES) {
			SQL_TYPES.put(new Integer(i), ValueType.DATE);
		}
		for (int i : DOUBLE_TYPES) {
			SQL_TYPES.put(new Integer(i), ValueType.DECIMAL);
		}
		for (int i : BOOLEAN_TYPES) {
			SQL_TYPES.put(new Integer(i), ValueType.BOOLEAN);
		}
	}
	// private static int numberOfKeysToGenerateAtATime = 100;

	/**
	 * are we to trace all sqls? Used during development/debugging
	 */
	private static boolean traceSqls;
	/**
	 * We use either DataSource, or connection string to connect to the data
	 * base. DataSource is preferred
	 */
	private static DbVendor dbVendor;
	private static DataSource dataSource;
	private static String connectionString;

	/*
	 * this is set ONLY if the app is set for multi-schema. Stored at the time
	 * of setting the db driver
	 */
	private static String defaultSchema = null;

	private static Map<String, DataSource> otherDataSources = null;
	private static Map<String, String> otherConStrings = null;

	/*
	 * RDBMS brand dependent settings. set based on db vendor
	 */
	private static String timeStampFn;
	private static String[] charsToEscapeForLike;

	/**
	 * an open connection is maintained during execution of call back
	 */
	private Connection connection;

	/**
	 * stated access type that is checked for consistency during subsequent
	 * calls
	 */
	private DbAccessType accessType;

	/**
	 * set up to be called before any db operation can be done
	 *
	 * @param vendor
	 * @param dataSourceName
	 * @param driverClassName
	 * @param conString
	 * @param logSqls
	 * @param schemaDetails
	 */
	public static synchronized void initialSetup(DbVendor vendor,
			String dataSourceName, String driverClassName, String conString,
			boolean logSqls, SchemaDetail[] schemaDetails) {
		if (vendor == null) {
			Tracer.trace(
					"This Application has not set dbVendor. We assume that the application does not require any db connection.");
			if (dataSourceName != null || driverClassName != null
					|| conString != null || schemaDetails != null) {
				Tracer.trace(
						"WARNING: Since dbVendor is not set, we ignore other db related settings.");
			}
			return;
		}
		setVendorParams(vendor);
		traceSqls = logSqls;
		/*
		 * use data source if specified
		 */
		if (dataSourceName != null) {
			if (driverClassName != null || conString != null) {
				Tracer.trace(
						"WARNING: Since dataSourceName is specified, we ignore driverClassName and connectionString attributes");
			}

			setDataSource(null, dataSourceName);

			if (schemaDetails != null) {
				otherDataSources = new HashMap<String, DataSource>();
				for (SchemaDetail sd : schemaDetails) {
					if (sd.schemaName == null || sd.dataSourceName == null) {
						throw new ApplicationError(
								"schemaName and dataSourceName are required for mutli-schema operation");
					}
					if (sd.connectionString != null) {
						Tracer.trace(
								"Warning : This application uses data source, and hence connection string for schema "
										+ sd.schemaName + " ignored");
					}
					setDataSource(sd.schemaName.toUpperCase(),
							sd.dataSourceName);
				}
			}
			return;
		}

		/*
		 * connection string
		 */
		if (driverClassName == null) {
			throw new ApplicationError("dbVendor is set to " + vendor
					+ " but no dataSource or driverClassName specified. If you do not need db connection, do not set dbVendor attribute.");
		}

		if (conString == null) {
			throw new ApplicationError(
					"driveClassName is specified but connection string is missing in your application set up.");
		}
		try {
			Class.forName(driverClassName);
		} catch (Exception e) {
			throw new ApplicationError(e, "Could not use class "
					+ driverClassName + " as driver class name.");
		}
		Tracer.trace("Driver class name " + driverClassName
				+ " invoked successfully");

		setConnection(null, conString);
		if (schemaDetails != null) {
			Tracer.trace("Checking connection string for additional schemas");
			otherConStrings = new HashMap<String, String>();
			for (SchemaDetail sd : schemaDetails) {
				if (sd.schemaName == null || sd.connectionString == null) {
					throw new ApplicationError(
							"schemaName and connectionString are required for mutli-schema operation");
				}
				if (sd.dataSourceName != null) {
					Tracer.trace(
							"Warning: This application uses connection string, and hence dataSource for schema "
									+ sd.schemaName + " ignored");
				}
				setConnection(sd.schemaName.toUpperCase(), sd.connectionString);
			}
		}
	}

	/**
	 */
	private static void setDataSource(String schema, String dataSourceName) {
		Object obj = null;
		String msg = null;
		try {
			obj = new InitialContext().lookup(dataSourceName);
		} catch (Exception e) {
			if (dataSourceName.startsWith(CONTEXT_PREFIX)) {
				msg = e.getMessage();
			} else {
				try {
					obj = new InitialContext()
							.lookup(CONTEXT_PREFIX + dataSourceName);
				} catch (Exception e1) {
					msg = e1.getMessage();
				}
			}
		}
		if (obj == null) {
			throw new ApplicationError("Error while using data source name "
					+ dataSourceName + "\n" + msg);
		}
		if (obj instanceof DataSource == false) {
			throw new ApplicationError("We got an object instance of "
					+ obj.getClass().getName() + " as data source for name "
					+ dataSourceName + " while we were expecting a "
					+ DataSource.class.getName());
		}
		DataSource ds = (DataSource) obj;
		Connection con = null;
		ApplicationError err = null;
		try {
			con = ds.getConnection();
			if (schema == null) {
				defaultSchema = extractDefaultSchema(con);
			}
			if (schema == null) {
				dataSource = ds;
				Tracer.trace("Database connection for " + dbVendor
						+ " established successfully using dataSource. Default schema is "
						+ defaultSchema);
			} else {
				otherDataSources.put(schema.toUpperCase(), ds);
				Tracer.trace("DataSource added for schema " + schema);
			}
		} catch (SQLException e) {
			err = new ApplicationError(e,
					"Data source is initialized but error while opening connection.");
		} finally {
			try {
				if (con != null) {
					con.close();
				}
			} catch (Exception ignore) {
				//
			}
		}
		if (err != null) {
			throw err;
		}
	}

	/**
	 * set connection string for a schema after testing it
	 *
	 * @param schema
	 * @param conString
	 */
	private static void setConnection(String schema, String conString) {
		Connection con = null;
		Exception err = null;
		try {
			con = DriverManager.getConnection(conString);
			if (schema == null) {
				defaultSchema = extractDefaultSchema(con);
				connectionString = conString;
				Tracer.trace("Database connection for " + dbVendor
						+ " established successfully using a valid connection string. Default schema is "
						+ defaultSchema);
			} else {
				otherConStrings.put(schema.toUpperCase(), conString);
				Tracer.trace(
						"Additional connection string validated for schema "
								+ schema);
			}
		} catch (Exception e) {
			err = e;
		} finally {
			try {
				if (con != null) {
					con.close();
				}
			} catch (Exception ignore) {
				//
			}
		}
		if (err != null) {
			throw new ApplicationError(err,
					" Database set up using connection string failed after successfully setting the driver for "
							+ (schema == null ? " default schema"
									: (" schema " + schema)));
		}
	}

	/**
	 * set parameters that depend on the selected vendor
	 *
	 * @param vendor
	 */
	private static void setVendorParams(DbVendor vendor) {
		Tracer.trace("dbVendor is set to " + vendor);
		dbVendor = vendor;
		char[] chars = vendor.getEscapesForLike();
		charsToEscapeForLike = new String[chars.length];
		for (int i = 0; i < chars.length; i++) {
			charsToEscapeForLike[i] = chars[i] + "";
		}

		timeStampFn = vendor.getTimeStamp();
	}

	/**
	 * only way to get an instance of RdbDriver to do rdbms operations.
	 * Necessary resources are allotted, and the passed object is called back
	 * with workWithDriver(instance)
	 *
	 * @param callBackObject
	 * @param accessType
	 */
	public static void workWithDriver(DbClientInterface callBackObject,
			DbAccessType accessType) {
		workWithDriver(callBackObject, accessType, null);
	}

	/**
	 * only way to get an instance of RdbDriver to do rdbms operations.
	 * Necessary resources are allotted, and the passed object is called back
	 * with workWithDriver(instance)
	 *
	 * @param callBackObject
	 * @param accType
	 * @param schema
	 *            optional. Use Only if your application is designed to work with
	 *            multiple schemas, AND this session transaction need to use a
	 *            schema different from the default one
	 */
	public static void workWithDriver(DbClientInterface callBackObject,
			DbAccessType accType, String schema) {
		Connection con = null;
		if (accType != DbAccessType.NONE) {
			con = getConnection(accType, schema);
		}
		DbDriver driver = new DbDriver(con, accType);
		boolean allOk = false;
		Exception exception = null;
		try {
			allOk = callBackObject.workWithDriver(driver);
		} catch (Exception e) {
			Tracer.trace(e,
					"Callback object threw an exception while working with the driver");
			exception = e;
		}
		if (con != null) {
			closeConnection(con, accType, allOk);
		}
		if (exception != null) {
			String msg = "Error while executing a service. "
					+ exception.getMessage();
			throw new ApplicationError(exception, msg);
		}
	}

	/**
	 * get a connection to the db
	 *
	 * @param acType
	 * @param schema
	 * @return connection
	 */
	static Connection getConnection(DbAccessType acType, String schema) {
		/*
		 * set sch to an upper-cased schema, but only if it is non-null and
		 * different from default schema
		 */
		String sch = null;
		if (schema != null) {
			sch = schema.toUpperCase();
			if (sch.equals(defaultSchema)) {
				Tracer.trace("service is asking for schema " + schema
						+ " but that is the default. default connection used");
				sch = null;
			} else {
				Tracer.trace("Going to open a non-default connection for schema "
						+ schema);
			}
		}
		Connection con = null;
		Exception err = null;
		try {
			con = createConnection(schema);
			if (acType != null) {
				if (acType == DbAccessType.READ_ONLY) {
					con.setReadOnly(true);
				} else {
					con.setTransactionIsolation(
							Connection.TRANSACTION_READ_COMMITTED);
					con.setAutoCommit(acType == DbAccessType.AUTO_COMMIT);
				}
			}
		} catch (Exception e) {
			if (con != null) {
				try {
					con.close();
				} catch (Exception e1) {
					//
				}
				con = null;
			}
			err = e;
		}
		if (con == null) {
			if (err == null) {
				throw new ApplicationError("Unable to connect to DataBase");
			}
			throw new ApplicationError(err, "Unable to connect to DataBase");
		}
		return con;
	}

	/**
	 * get a connection to the db
	 *
	 * @param acType
	 * @param schema
	 * @return connection
	 * @throws SQLException
	 */
	private static Connection createConnection(String schema)
			throws SQLException {
		/*
		 * set sch to an upper-cased schema, but only if it is non-null and
		 * different from default schema
		 */
		String sch = null;
		if (schema != null) {
			sch = schema.toUpperCase();
			if (sch.equals(defaultSchema)) {
				Tracer.trace("service is asking for schema " + schema
						+ " but that is the default. default connection used");
				sch = null;
			} else {
				Tracer.trace("Going to open a non-default connection for schema "
						+ schema);
			}
		}
		if (dataSource != null) {
			/*
			 * this application uses dataSource
			 */
			if (sch == null) {
				return dataSource.getConnection();
			}
			/*
			 * this service is using a different schema
			 */
			DataSource ds = otherDataSources.get(sch);
			if (ds == null) {
				throw new ApplicationError(
						"No dataSource configured for schema " + sch);
			}
			return ds.getConnection();

		}
		if (connectionString == null) {
			throw new ApplicationError(
					"Database should be initialized properly before any operation can be done.");
		}
		/*
		 * old-fashioned application :-(
		 */
		if (sch == null) {
			return DriverManager.getConnection(connectionString);
		}
		/*
		 * service uses a non-default schema
		 */
		String conString = otherConStrings.get(sch);
		if (conString == null) {
			throw new ApplicationError(
					"No connection string configured for schema " + sch);
		}
		return DriverManager.getConnection(conString);
	}

	/**
	 * private constructor to ensure that we control its instantiation
	 *
	 * @param con
	 * @param dbAccessType
	 */
	private DbDriver(Connection con, DbAccessType dbAccessType) {
		this.connection = con;
		this.accessType = dbAccessType;
	}

	/**
	 * extract output from sql into data sheet
	 *
	 * @param sql
	 *            must be a single prepared sql, with no semicolon at the end.
	 * @param values
	 *            to be put into the prepared sql
	 * @param outSheet
	 *            data sheet that has the expected columns defined in it.
	 * @param oneRowOnly
	 *            true if (at most) one row is to be extracted. false to extract
	 *            all rows
	 * @return number of rows extracted
	 */
	public int extractFromSql(String sql, Value[] values, DataSheet outSheet,
			boolean oneRowOnly) {
		if (traceSqls) {
			this.traceSql(sql, values);
			if (this.connection == null) {
				return 0;
			}
		}
		PreparedStatement stmt = null;
		int result = 0;
		try {
			stmt = this.connection.prepareStatement(sql);
			this.setParams(stmt, values);
			if (oneRowOnly) {
				return this.extractOne(stmt, outSheet);
			}
			result = this.extractAll(stmt, outSheet);
		} catch (SQLException e) {
			throw new ApplicationError(e, "Sql Error while extracting data ");
		} finally {
			this.closeStatment(stmt);
		}
		return result;
	}

	/**
	 * check if this sql result sin at least one row
	 *
	 * @param sql
	 * @param values
	 * @return true if there is at least one row
	 */
	public boolean hasResult(String sql, Value[] values) {
		if (traceSqls) {
			this.traceSql(sql, values);
			if (this.connection == null) {
				return false;
			}
		}
		PreparedStatement stmt = null;
		boolean result = false;
		try {
			stmt = this.connection.prepareStatement(sql);
			this.setParams(stmt, values);
			ResultSet rs = stmt.executeQuery();
			if (rs.next()) {
				result = true;
			}
			rs.close();
		} catch (SQLException e) {
			throw new ApplicationError(e, "Sql Error while extracting data ");
		} finally {
			this.closeStatment(stmt);
		}
		return result;
	}

	/**
	 * extract output from sql with different sets of input values into data
	 * sheet
	 *
	 * @param sql
	 *            must be a single prepared sql, with no semicolon at the end.
	 * @param values
	 *            to be put into the prepared sql, one row per batch
	 * @param outSheet
	 *            data sheet that has the expected columns defined in it.
	 * @return number of rows extracted
	 */
	public int extractFromSql(String sql, Value[][] values,
			DataSheet outSheet) {
		if (traceSqls) {
			this.traceBatchSql(sql, values);
			if (this.connection == null) {
				return 0;
			}
		}
		PreparedStatement stmt = null;
		int total = 0;
		try {
			stmt = this.connection.prepareStatement(sql);
			for (Value[] vals : values) {
				this.setParams(stmt, vals);
				total += this.extractAll(stmt, outSheet);
			}
		} catch (SQLException e) {
			throw new ApplicationError(e, "Sql Error while extracting data ");
		} finally {
			this.closeStatment(stmt);
		}
		return total;
	}

	/**
	 * extract output from sql that the caller has o idea about the output
	 * columns
	 *
	 * @param sql
	 *            must be a single prepared sql, with no semicolon at the end.
	 * @param values
	 *            to be put into the prepared sql
	 * @param oneRowOnly
	 *            true if (at most) one row is to be extracted. false to extract
	 *            all rows
	 * @return a data sheet with has 0 or more rows of extracted data
	 */
	public DataSheet extractFromDynamicSql(String sql, Value[] values,
			boolean oneRowOnly) {
		if (traceSqls) {
			this.traceSql(sql, values);
			if (this.connection == null) {
				return null;
			}
		}
		PreparedStatement stmt = null;
		DataSheet result = null;
		try {
			stmt = this.connection.prepareStatement(sql);
			this.setParams(stmt, values);
			if (oneRowOnly) {
				return this.extractMetaOne(stmt);
			}
			result = this.extractMetaAll(stmt);
		} catch (SQLException e) {
			throw new ApplicationError(e, "Sql Error while extracting data ");
		} finally {
			this.closeStatment(stmt);
		}
		return result;
	}

	/**
	 * execute a sql as a prepared statement
	 *
	 * @param sql
	 *            to be executed
	 * @param values
	 *            in the right order for the prepared statement
	 * @param treatSqlErrorAsNoAction
	 *            if true, sql error is treated as if rows affected is zero.
	 *            This is helpful when constraints are added in the db, and we
	 *            would treat failure as validation issue.
	 * @return number of affected rows
	 */
	public int executeSql(String sql, Value[] values,
			boolean treatSqlErrorAsNoAction) {
		PreparedStatement stmt = null;
		if (traceSqls) {
			this.traceSql(sql, values);
			if (this.connection == null) {
				return 0;
			}
		}
		this.checkWritable();
		int result = 0;
		try {
			stmt = this.connection.prepareStatement(sql);
			this.setParams(stmt, values);
			result = stmt.executeUpdate();
		} catch (SQLException e) {
			if (treatSqlErrorAsNoAction) {
				Tracer.trace("SQLException code:" + e.getErrorCode()
				+ " message :" + e.getMessage()
				+ " is treated as zero rows affected.");
			} else {
				throw new ApplicationError(e, "Sql Error while executing sql ");
			}
		} finally {
			this.closeStatment(stmt);
		}
		if (result < 0) {
			Tracer.trace(
					"Number of affected rows is not reliable as we got it as "
							+ result);
		} else {
			Tracer.trace(result + " rows affected.");
		}
		return result;
	}

	/**
	 * execute an insert statement as a prepared statement
	 *
	 * @param sql
	 *            to be executed
	 * @param values
	 *            in the right order for the prepared statement
	 * @param generatedKeys
	 *            array in which generated keys are returned
	 * @param keyNames
	 *            array of names of columns that have generated keys. This is
	 *            typically just one, primary key
	 * @param treatSqlErrorAsNoAction
	 *            if true, sql error is treated as if rows affected is zero.
	 *            This is helpful when constraints are added in the db, and we
	 *            would treat failure as validation issue.
	 * @return number of affected rows
	 */
	public int insertAndGetKeys(String sql, Value[] values,
			long[] generatedKeys, String[] keyNames,
			boolean treatSqlErrorAsNoAction) {
		PreparedStatement stmt = null;
		if (traceSqls) {
			this.traceSql(sql, values);
			if (this.connection == null) {
				return 0;
			}
		}
		this.checkWritable();
		int result = 0;
		try {
			stmt = this.connection.prepareStatement(sql, keyNames);
			this.setParams(stmt, values);
			result = stmt.executeUpdate();
			if (result > 0) {
				this.getGeneratedKeys(stmt, generatedKeys);
			}
		} catch (SQLException e) {
			if (treatSqlErrorAsNoAction) {
				Tracer.trace("SQLException code:" + e.getErrorCode()
				+ " message :" + e.getMessage()
				+ " is treated as zero rows affected.");
			} else {
				throw new ApplicationError(e, "Sql Error while executing sql ");
			}
		} finally {
			this.closeStatment(stmt);
		}
		if (result < 0) {
			Tracer.trace(
					"Number of affected rows is not reliable as we got it as "
							+ result);
		} else {
			Tracer.trace(result + " rows affected.");
		}
		return result;
	}

	/**
	 * extract generated keys into the array
	 *
	 * @param stmt
	 * @param generatedKeys
	 * @throws SQLException
	 */
	private void getGeneratedKeys(Statement stmt, long[] generatedKeys)
			throws SQLException {

		ResultSet rs = stmt.getGeneratedKeys();
		for (int i = 0; i < generatedKeys.length && rs.next(); i++) {
			generatedKeys[i] = rs.getLong(1);
		}
		rs.close();
	}

	/**
	 * for each row in the result set of the sql, call back the iterator.
	 *
	 * @param sql
	 * @param values
	 *            for the sql
	 * @param outputTypes
	 *            value types of output parameters. null if you want us to
	 *            discover it, but it will cost you a few grands :-)
	 * @param iterator
	 *            to be called back with workWithARow(row) method. iteration
	 *            stops if this method returns false;
	 * @return number of rows iterated
	 */
	public int workWithRows(String sql, Value[] values, ValueType[] outputTypes,
			RowIterator iterator) {
		PreparedStatement stmt = null;
		try {
			stmt = this.connection.prepareStatement(sql);
			this.setParams(stmt, values);
			return this.iterate(stmt, outputTypes, iterator);
		} catch (SQLException e) {
			throw new ApplicationError(e, "Sql Error executing service ");
		} finally {
			this.closeStatment(stmt);
		}
	}

	/**
	 * execute a prepared statement, with different sets of values
	 *
	 * @param sql
	 * @param values
	 *            each row should have the same number of values, in the right
	 *            order for the sql
	 * @param treatSqlErrorAsNoAction
	 *            if true, sql error is treated as if rows affected is zero.
	 *            This is helpful when constraints are added in the db, and we
	 *            would treat failure as validation issue.
	 * @return affected rows for each set of values
	 */
	public int[] executeBatch(String sql, Value[][] values,
			boolean treatSqlErrorAsNoAction) {
		if (traceSqls) {
			this.traceBatchSql(sql, values);
			if (this.connection == null) {
				return new int[0];
			}
		}
		this.checkWritable();
		PreparedStatement stmt = null;
		int[] result = new int[0];
		try {
			stmt = this.connection.prepareStatement(sql);
			for (Value[] row : values) {
				this.setParams(stmt, row);
				stmt.addBatch();
			}
			result = stmt.executeBatch();
		} catch (SQLException e) {
			if (treatSqlErrorAsNoAction) {
				Tracer.trace("SQLException code:" + e.getErrorCode()
				+ " message :" + e.getMessage()
				+ " is treated as zero rows affected.");
			} else {
				throw new ApplicationError(e,
						"Sql Error while executing batch ");
			}
		} finally {
			this.closeStatment(stmt);
		}
		int rows = 0;
		for (int j : result) {
			if (j < 0) {
				rows = j;
			} else if (rows >= 0) {
				rows += j;
			}
		}
		if (rows < 0) {
			Tracer.trace(
					"Number of affected rows is not reliable as we got it as "
							+ rows);
		} else {
			Tracer.trace(rows + " rows affected.");
		}
		return result;
	}

	/**
	 * extract output from stored procedure into data sheet
	 *
	 * @param sql
	 *            must be in the standard jdbc format {call
	 *            procedureName(?,?,...)}
	 * @param inputFields
	 * @param outputFields
	 * @param params
	 * @param outputSheets
	 * @param ctx
	 * @return number of rows extracted
	 */
	public int executeSp(String sql, FieldsInterface inputFields,
			FieldsInterface outputFields, ProcedureParameter[] params,
			DataSheet[] outputSheets, ServiceContext ctx) {
		if (traceSqls) {
			this.traceSql(sql, null);
			if (this.connection == null) {
				return 0;
			}
		}
		CallableStatement stmt = null;
		int result = 0;
		SQLException err = null;
		try {
			stmt = this.connection.prepareCall(sql);
			if (params != null) {
				for (ProcedureParameter param : params) {
					/*
					 * programmers often make mistakes while defining
					 * parameters. Better to pin-point such errors
					 */
					try {
						if (param.setParameter(stmt, inputFields,
								ctx) == false) {
							Tracer.trace("Error while setting " + param.name
									+ " You will get an error.");
							// issue in setting parameter. May be a mandatory
							// field is not set
							return 0;
						}
					} catch (Exception e) {
						Tracer.trace("Unable to set param " + param.name
								+ " error : " + e.getMessage());
						param.reportError(e);
					}
				}
			}
			boolean hasResult = stmt.execute();
			int i = 0;
			if (outputSheets != null && hasResult) {
				int nbrSheets = outputSheets.length;
				while (hasResult) {
					if (i >= nbrSheets) {
						Tracer.trace(
								"Stored procedure is ready to give more results, but the requester has supplied only "
										+ nbrSheets
										+ " data sheets to read data into. Other data ignored.");
						break;
					}
					DataSheet outputSheet = outputSheets[i];
					ValueType[] outputTypes = outputSheet.getValueTypes();
					ResultSet rs = stmt.getResultSet();
					while (rs.next()) {
						outputSheet.addRow(getParams(rs, outputTypes));
						result++;
					}
					rs.close();
					i++;
					hasResult = stmt.getMoreResults();
				}
			}
			if (params != null) {
				for (ProcedureParameter param : params) {
					/*
					 * programmers often make mistakes while defining
					 * parameters. Better to pin-point such errors
					 */
					try {
						param.extractOutput(stmt, outputFields, ctx);
					} catch (Exception e) {
						param.reportError(e);
					}
				}
			}
		} catch (SQLException e) {
			err = e;
		} finally {
			this.closeStatment(stmt);
		}
		if (err != null) {
			throw new ApplicationError(err,
					"Sql Error while extracting data using stored procedure");
		}

		Tracer.trace(result + " rows extracted.");
		if (result > 0) {
			return result;
		}
		if (outputFields != null) {
			return 1;
		}
		return 0;
	}

	/**
	 * close connection after commit/roll-back
	 *
	 * @param allOk
	 *            if we are managing transaction, true implies commit, and false
	 *            implies roll-back
	 */
	static void closeConnection(Connection con, DbAccessType accType,
			boolean allOk) {
		try {
			Tracer.trace("Going to close a connection of type " + accType
					+ " with allOK = " + allOk);
			if (accType == DbAccessType.READ_WRITE) {
				if (allOk) {
					con.commit();
				} else {
					con.rollback();
				}
			}
		} catch (SQLException e) {
			// throw new ApplicationError(e,
			Tracer.trace(e, "Sql Error while closing database connection. ");
		} finally {
			try {
				con.close();
			} catch (Exception e) {
				//
			}
		}
	}

	/**
	 * sets parameters to prepared statement
	 *
	 * @param stmt
	 * @param values
	 *            First occurrence of null implies logical end of array. This
	 *            feature is added to avoid use of List
	 * @throws SQLException
	 */
	private void setParams(PreparedStatement stmt, Value[] values)
			throws SQLException {
		if (values == null) {
			return;
		}
		int i = 1;
		for (Value value : values) {
			value.setToStatement(stmt, i);
			i++;
		}
	}

	/**
	 * extract rows from a statement into a sheet
	 *
	 * @param stmt
	 * @param outSheet
	 * @return number rows extracted
	 * @throws SQLException
	 */
	private int extractAll(PreparedStatement stmt, DataSheet outSheet)
			throws SQLException {
		ValueType[] outputTypes = outSheet.getValueTypes();
		ResultSet rs = stmt.executeQuery();
		int result = 0;
		while (rs.next()) {
			outSheet.addRow(getParams(rs, outputTypes));
			result++;
		}
		rs.close();
		Tracer.trace(result + " rows extracted.");
		return result;
	}

	/**
	 * extract at most one row from a statement into a sheet
	 *
	 * @param stmt
	 * @param outSheet
	 * @return number rows extracted
	 * @throws SQLException
	 */
	private int extractOne(PreparedStatement stmt, DataSheet outSheet)
			throws SQLException {
		ResultSet rs = stmt.executeQuery();
		int result = 0;
		if (rs.next()) {
			outSheet.addRow(getParams(rs, outSheet.getValueTypes()));

			result = 1;
		}
		rs.close();
		Tracer.trace(result + " rows extracted.");
		return result;
	}

	/**
	 * @param stmt
	 * @return
	 * @throws SQLException
	 */
	private DataSheet extractMetaAll(PreparedStatement stmt)
			throws SQLException {
		ResultSet rs = stmt.executeQuery();
		DataSheet outSheet = this.createOutSheet(rs);
		this.extractAll(stmt, outSheet);
		rs.close();
		return outSheet;
	}

	/**
	 * @param stmt
	 * @return
	 * @throws SQLException
	 */
	private DataSheet extractMetaOne(PreparedStatement stmt)
			throws SQLException {
		ResultSet rs = stmt.executeQuery();
		DataSheet outSheet = new DynamicSheet();
		if (rs.next()) {
			ResultSetMetaData md = rs.getMetaData();
			int n = md.getColumnCount();
			for (int i = 1; i <= n; i++) {
				String colName = md.getColumnName(i);
				ValueType type = this.getValueType(md.getColumnType(i));
				Value value = type.extractFromRs(rs, i);
				outSheet.setValue(colName, value);
			}
		}
		rs.close();
		return outSheet;
	}

	/**
	 * extract rows from a statement
	 *
	 * @param stmt
	 * @param outputTypes
	 * @return number of rows iterated
	 * @throws SQLException
	 */
	private int iterate(PreparedStatement stmt, ValueType[] outputTypes,
			RowIterator iterator) throws SQLException {
		ResultSet rs = stmt.executeQuery();
		ValueType[] types = outputTypes == null ? this.getOutputTypes(rs)
				: outputTypes;
		int nbr = 0;
		while (rs.next()) {
			iterator.workWithARow(getParams(rs, types));
			nbr++;
		}
		rs.close();
		return nbr;

	}

	/**
	 * @param rs
	 * @return
	 * @throws SQLException
	 */
	private ValueType[] getOutputTypes(ResultSet rs) throws SQLException {
		ResultSetMetaData md = rs.getMetaData();
		int n = md.getColumnCount();
		ValueType[] types = new ValueType[n];
		for (int i = 0; i < types.length; i++) {
			int j = i + 1;
			ValueType type = SQL_TYPES.get(new Integer(md.getColumnType(j)));
			if (type == null) {
				type = ValueType.TEXT;
			}
			types[i] = type;
		}
		return types;
	}

	/**
	 * @param rs
	 * @return data sheet
	 * @throws SQLException
	 */
	private DataSheet createOutSheet(ResultSet rs) throws SQLException {
		ResultSetMetaData md = rs.getMetaData();
		int n = md.getColumnCount();
		ValueType[] types = new ValueType[n];
		String[] columnNames = new String[n];
		for (int i = 0; i < types.length; i++) {
			int j = i + 1;
			columnNames[i] = md.getColumnName(j);
			types[i] = this.getValueType(md.getColumnType(j));
		}
		return new MultiRowsSheet(columnNames, types);
	}

	private ValueType getValueType(int sqlType) {
		ValueType type = SQL_TYPES.get(new Integer(sqlType));
		if (type == null) {
			return ValueType.TEXT;
		}
		return type;
	}

	/**
	 * gets output parameters from a stored procedure
	 *
	 * @param stmt
	 * @param values
	 * @throws SQLException
	 */
	private static Value[] getParams(ResultSet rs, ValueType[] types)
			throws SQLException {
		Value[] values = new Value[types.length];
		for (int i = 0; i < types.length; i++) {
			values[i] = types[i].extractFromRs(rs, i + 1);
		}
		return values;
	}

	/**
	 * method to be used when the parameters to be extracted are not in the
	 * right order, or we are not extracting each of them, and the caller would
	 * like to specify the position.
	 *
	 * @param stmt
	 * @param values
	 * @throws SQLException
	 */
	private static Value[] getParams(ResultSet rs, ValueType[] types,
			int[] positions) throws SQLException {
		Value[] values = new Value[types.length];
		for (int i = 0; i < types.length; i++) {
			values[i] = types[i].extractFromRs(rs, positions[i]);
		}
		return values;
	}

	/**
	 * @param statement
	 */
	private void closeStatment(Statement statement) {
		if (statement == null) {
			return;
		}
		try {
			statement.close();
		} catch (Exception e) {
			//
		}
	}

	/**
	 * @return sql function to get time stamp
	 */
	public static String getTimeStamp() {
		return timeStampFn;
	}

	/**
	 * put % and escape the text suitable for a LIKE operation as per brand of
	 * RDBMS. we have standardized on ! as escape character
	 *
	 * @param text
	 *            to be escaped
	 * @return go ahead and send this as value of prepared statement for LIKE
	 */
	public static String escapeForLike(String text) {
		String result = text.replaceAll(OUR_ESCAPE_CHAR, OUR_ESCAPE_STR);
		for (String s : charsToEscapeForLike) {
			result = result.replace(s, OUR_ESCAPE_CHAR + s);
		}
		return result;
	}

	private void traceSql(String sql, Value[] values) {
		if (values == null || values.length == 0) {
			Tracer.trace(sql);
			return;
		}
		StringBuilder sbf = new StringBuilder(sql);
		sbf.append("\n Parameters");
		int i = 0;
		for (Value value : values) {
			if (value == null) {
				break;
			}
			i++;
			sbf.append('\n').append(i).append(" : ").append(value.toString());
			if (i > 12) {
				sbf.append("..like wise up to ").append(values.length)
				.append(" : ").append(values[values.length - 1]);
				break;
			}
		}
		Tracer.trace(sbf.toString());
	}

	private void traceBatchSql(String sql, Value[][] values) {
		StringBuilder sbf = new StringBuilder(sql);
		int i = 0;
		for (Value[] row : values) {
			if (row == null) {
				break;
			}
			i++;
			sbf.append("\n SET ").append(i);
			int j = 0;
			for (Value value : row) {
				if (value == null) {
					break;
				}
				j++;
				sbf.append('\n').append(j).append(" : ").append(value);
			}
		}
		// Tracer.trace(sbf.toString());
	}

	/**
	 * get tables/views defined in the database
	 *
	 * @param schemaName
	 *            null, pattern or name
	 * @param tableName
	 *            null, pattern or name
	 * @return data sheet that has attributes for tables/views. Null if no
	 *         output
	 */
	public static DataSheet getTables(String schemaName, String tableName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, tableName, TABLE_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get column names of a table
	 *
	 * @param schemaName
	 *            schema to which this table belongs to. leave it null to get
	 *            the table from default schema
	 * @param tableName
	 *            can be null to get all tables or pattern, or actual name
	 * @return sheet with one row per column. Null if no columns.
	 */
	public static DataSheet getTableColumns(String schemaName,
			String tableName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, tableName, COL_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get key columns for all tables in the schema
	 *
	 * @param schemaName
	 * @return sheet with one row per column. Null if this table does not exist,
	 *         or something went wrong!!
	 */
	public static DataSheet getPrimaryKeys(String schemaName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, null, KEY_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get key columns names of a table
	 *
	 * @param schemaName
	 *            possibly null
	 * @param tableName
	 *            non-null
	 * @return key column names
	 */
	public static String[] getPrimaryKeysForTable(String schemaName,
			String tableName) {
		if (tableName == null) {
			Tracer.trace(
					"getPrimaryKeysForTable() is for a specific table. If you want for all tables, use the getPrimaryKeys()");
			return null;
		}
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			DataSheet sheet = getMetaSheet(con, schemaName, tableName, KEY_IDX);
			if (sheet == null) {
				return null;
			}
			int n = sheet.length();
			String[] result = new String[n];
			for (int i = 0; i < n; i++) {
				Value[] row = sheet.getRow(i);
				int idx = (int) ((IntegerValue) row[1]).getLong() - 1;
				result[idx] = row[0].toString();
			}
			return result;
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get stored procedures
	 *
	 * @param schemaName
	 *            null, pattern or name
	 * @param procedureName
	 *            null, pattern or name
	 * @return data sheet that has attributes of procedures. Null if no output
	 */
	public static DataSheet getProcedures(String schemaName,
			String procedureName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, procedureName, PROC_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get parameters of procedure
	 *
	 * @param schemaName
	 *            null, pattern or name
	 * @param procedureName
	 *            null, pattern or name
	 * @return sheet with one row per column. Null if this table does not exist,
	 *         or something went wrong!!
	 */
	public DataSheet getProcedureParams(String schemaName,
			String procedureName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, procedureName, PARAM_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get structures/user defined types
	 *
	 * @param schemaName
	 *            null, pattern, or name
	 * @param structName
	 *            null or pattern.
	 * @return data sheet containing attributes of structures. Null of no output
	 */
	public DataSheet getStructs(String schemaName, String structName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, structName, STRUCT_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	/**
	 * get attributes of structure (user defined data type)
	 *
	 * @param schemaName
	 *            null for all or pattern/name
	 * @param structName
	 *            null for all or pattern/name
	 * @return sheet with one row per column. Null if no output
	 */
	public DataSheet getStructAttributes(String schemaName, String structName) {
		Connection con = getConnection(DbAccessType.READ_ONLY, schemaName);
		try {
			return getMetaSheet(con, schemaName, structName, ATTR_IDX);
		} finally {
			closeConnection(con, DbAccessType.READ_ONLY, true);
		}
	}

	private static DataSheet getMetaSheet(Connection con, String schema,
			String metaName, int metaIdx) {
		ResultSet rs = null;
		String schemaName = schema;
		if (schema == null) {
			schemaName = defaultSchema;
		}
		try {
			DatabaseMetaData meta = con.getMetaData();
			switch (metaIdx) {
			case TABLE_IDX:
				rs = meta.getTables(null, schemaName, metaName,
						TABLE_TYPES_TO_EXTRACT);
				break;
			case COL_IDX:
				rs = meta.getColumns(null, schemaName, metaName, null);
				break;
			case KEY_IDX:
				rs = meta.getPrimaryKeys(null, schemaName, metaName);
				break;
			case PROC_IDX:
				rs = meta.getProcedures(null, schemaName, metaName);
				break;
			case PARAM_IDX:
				rs = meta.getProcedureColumns(null, schemaName, metaName, null);
				break;
			case STRUCT_IDX:
				rs = meta.getUDTs(null, schemaName, metaName,
						STRUCT_TYPES_TO_EXTRACT);
				break;
			case ATTR_IDX:
				rs = meta.getAttributes(null, schemaName, metaName, null);
				break;
			default:
				throw new ApplicationError(
						"Meta data " + metaIdx + " is not defined yet.");
			}
			if (rs.next()) {
				DataSheet sheet = new MultiRowsSheet(META_COLUMNS[metaIdx],
						META_TYPES[metaIdx]);
				do {
					sheet.addRow(getParams(rs, META_TYPES[metaIdx],
							META_POSNS[metaIdx]));
				} while (rs.next());
				return sheet;
			}
		} catch (Exception e) {
			Tracer.trace(e, "Unable to get meta data for " + metaName);
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e) {
					//
				}
			}
		}
		return null;
	}

	/**
	 * @return db vendor from whom the driver is used
	 */
	public static DbVendor getDbVendor() {
		return dbVendor;
	}

	/**
	 *
	 * @param con
	 * @param schema
	 */
	private static String extractDefaultSchema(Connection con) {
		String schema = null;
		try {
			Statement stmt = con.createStatement();
			stmt.executeQuery(dbVendor.getGetSchemaSql());
			ResultSet rs = stmt.getResultSet();
			if (rs.next()) {
				schema = rs.getString(1);
				if (rs.wasNull()) {
					throw new ApplicationError(
							"data base returned null as default schema.");
				}
			} else {
				throw new ApplicationError(
						"data base returned no result for sql "
								+ dbVendor.getGetSchemaSql());
			}
		} catch (SQLException e) {
			throw new ApplicationError(e,
					"Error while getting default schema for this db connection.");
		}
		return schema.toUpperCase();
	}

	/**
	 * @return default schema or null
	 */
	public static Object getDefaultSchema() {
		return defaultSchema;
	}

	/**
	 * @return true if the db vendor needs a key generator , like oracle
	 */
	public static boolean generatorNameRequired() {
		return dbVendor == DbVendor.ORACLE;
	}

	private void checkWritable() {
		if (this.accessType == DbAccessType.READ_ONLY) {
			throw new ApplicationError(
					"Service is set for read-only access to database, but an attempt is made to manipulate data");
		}
	}

	/**
	 * @param schema
	 *            name of schema to check for
	 * @return true is this schema is defined as additional schema. False
	 *         otherwise
	 */
	public static boolean isSchmeaDefined(String schema) {
		if (schema == null) {
			return false;
		}
		String sn = schema.toUpperCase();
		if (sn.equals(defaultSchema)) {
			return true;
		}
		if (dataSource != null) {
			if (otherDataSources != null && otherDataSources.containsKey(sn)) {
				return true;
			}
			return false;
		}
		if (otherConStrings != null && otherConStrings.containsKey(sn)) {
			return true;
		}
		return false;
	}

	/*
	 * methods related to data structure/object in db,
	 */

	/**
	 * delegated back to DBDriver to take care of driver related issues between
	 * Oracle and standard SQL
	 *
	 * @param con
	 * @param values
	 * @param dbArrayType
	 *            as defined in the RDBMS
	 * @return object that is suitable to be assigned to an array parameter
	 * @throws SQLException
	 */
	public static Array createArray(Connection con, Value[] values,
			String dbArrayType) throws SQLException {
		Object[] data = new Object[values.length];
		for (int i = 0; i < values.length; i++) {
			Value val = values[i];
			if (val != null) {
				data[i] = val.toObject();
			}
		}
		if (dbVendor == DbVendor.ORACLE) {
			OracleConnection ocon = toOracleConnection(con);
			ArrayDescriptor ad = ArrayDescriptor.createDescriptor(dbArrayType,
					ocon);
			return new ARRAY(ad, ocon, data);
		}
		return con.createArrayOf(dbArrayType, data);
	}

	/**
	 * This is delegated back to DbDriver because oracle driver does not support
	 * standard SQL way of doing this. Let DbDriver class be the repository of
	 * all Driver related issues
	 *
	 * @param con
	 * @param data
	 * @param dbObjectType
	 *            as defined in RDBMS
	 * @return object that can be assigned to a struct parameter
	 * @throws SQLException
	 */
	public static Struct createStruct(Connection con, Object[] data,
			String dbObjectType) throws SQLException {
		if (dbVendor == DbVendor.ORACLE) {
			OracleConnection ocon = toOracleConnection(con);
			StructDescriptor sd = StructDescriptor
					.createDescriptor(dbObjectType, ocon);
			return new STRUCT(sd, ocon, data);
		}
		return con.createStruct(dbObjectType, data);
	}

	/**
	 * This is delegated back to DbDriver because oracle driver does not support
	 * standard SQL way of doing this. Let DbDriver class be the repository of
	 * all Driver related issues
	 *
	 * @param con
	 * @param values
	 * @param dbObjectType
	 *            as defined in RDBMS
	 * @return object that can be assigned to a struct parameter
	 * @throws SQLException
	 */
	public static Struct createStruct(Connection con, Value[] values,
			String dbObjectType) throws SQLException {
		Object[] data = new Object[values.length];
		for (int i = 0; i < values.length; i++) {
			Value value = values[i];
			if (value != null) {
				data[i] = value.toObject();
			}
		}
		return createStruct(con, data, dbObjectType);
	}

	/**
	 * Create a struct array that can be assigned to procedure parameter. This
	 * is delegated to DBDriver because of issues with Oracle driver
	 *
	 * @param con
	 * @param structs
	 * @param dbArrayType
	 *            as defined in the rdbms
	 * @return object that is suitable to be assigned to stored procedure
	 *         parameter
	 * @throws SQLException
	 */
	public static Array createStructArray(Connection con, Struct[] structs,
			String dbArrayType) throws SQLException {
		if (dbVendor == DbVendor.ORACLE) {
			OracleConnection ocon = toOracleConnection(con);
			ArrayDescriptor ad = ArrayDescriptor.createDescriptor(dbArrayType,
					ocon);
			return new ARRAY(ad, ocon, structs);
		}
		return con.createArrayOf(dbArrayType, structs);
	}

	private static OracleConnection toOracleConnection(Connection con) {
		if (con instanceof OracleConnection) {
			return (OracleConnection) con;
		}
		try {
			return con.unwrap(OracleConnection.class);
		} catch (Exception e) {
			throw new ApplicationError(
					"Error while unwrapping to Oracle connection. This is a set-up issue with your server. It is probably using a pooled-connection with a flag not to allow access to underlying connection object "
							+ e.getMessage());
		}
	}

	/**
	 * not recommended for use. Use only under strict parental supervision.
	 * ensure that you close it properly
	 *
	 * @return connection object that MUST be closed by you at any cost!!
	 */
	public static Connection getConnection() {
		return getConnection(null, null);
	}
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;

namespace QuantConnect.Algorithm.Examples
{
    /// <summary>
    /// ETF Global Rotation Strategy
    /// </summary>
    public class ETFGlobalRotationAlgorithm : QCAlgorithm
    {
        // we'll use this to tell us when the month has ended
        DateTime LastRotationTime = DateTime.MinValue;
        TimeSpan RotationInterval = TimeSpan.FromDays(30);
        private bool first = true;

        // these are the growth symbols we'll rotate through
        List<string> GrowthSymbols = new List<string>
        {
            "MDY", // US S&P mid cap 400
            "IEV", // iShares S&P europe 350
            "EEM", // iShared MSCI emerging markets
            "ILF", // iShares S&P latin america
            "EPP"  // iShared MSCI Pacific ex-Japan
        };

        // these are the safety symbols we go to when things are looking bad for growth
        List<string> SafetySymbols = new List<string>
        {
            "EDV", // Vangaurd TSY 25yr+
            "SHY"  // Barclays Low Duration TSY
        };

        // we'll hold some computed data in these guys
        List<SymbolData> SymbolData = new List<SymbolData>();

        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        public override void Initialize()
        {
            SetCash(25000);
            SetStartDate(2007, 1, 1);

            foreach (var symbol in GrowthSymbols.Union(SafetySymbols))
            {
                // ideally we would use daily data
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
                var oneMonthPerformance = MOM(symbol, 30, Resolution.Daily);
                var threeMonthPerformance = MOM(symbol, 90, Resolution.Daily);

                SymbolData.Add(new SymbolData
                {
                    Symbol = symbol,
                    OneMonthPerformance = oneMonthPerformance,
                    ThreeMonthPerformance = threeMonthPerformance
                });
            }
        }

        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            try
            {
                // the first time we come through here we'll need to do some things such as allocation
                // and initializing our symbol data
                if (first)
                {
                    first = false;
                    LastRotationTime = data.Time;
                    return;
                }

                var delta = data.Time.Subtract(LastRotationTime);
                if (delta > RotationInterval)
                {
                    LastRotationTime = data.Time;

                    // pick which one is best from growth and safety symbols
                    var orderedObjScores = SymbolData.OrderByDescending(x => x.ObjectiveScore).ToList();
                    foreach (var orderedObjScore in orderedObjScores)
                    {
                        Log(">>SCORE>>" + orderedObjScore.Symbol + ">>" + orderedObjScore.ObjectiveScore);
                    }
                    var bestGrowth = orderedObjScores.First();

                    if (bestGrowth.ObjectiveScore > 0)
                    {
                        if (Portfolio[bestGrowth.Symbol].Quantity == 0)
                        {
                            Log("PREBUY>>LIQUIDATE>>");
                            Liquidate();
                        }
                        Log(">>BUY>>" + bestGrowth.Symbol + "@" + (100 * bestGrowth.OneMonthPerformance).ToString("00.00"));
                        decimal qty = Portfolio.Cash / Securities[bestGrowth.Symbol].Close;
                        Order(bestGrowth.Symbol, qty, OrderType.Market);
                    }
                    else
                    {
                        // if no one has a good objective score then let's hold cash this month to be safe
                        Log(">>LIQUIDATE>>CASH");
                        Liquidate();
                    }
                }
            }
            catch (Exception ex)
            {
                Error("OnTradeBar: " + ex.Message + "\r\n\r\n" + ex.StackTrace);
            }
        }
    }

    class SymbolData
    {
        public string Symbol;

        public Momentum OneMonthPerformance { get; set; }
        public Momentum ThreeMonthPerformance { get; set; }

        public decimal ObjectiveScore
        {
            get
            {
                // we weight the one month performance higher
                decimal weight1 = 100;
                decimal weight2 = 75;

                return (weight1 * OneMonthPerformance + weight2 * ThreeMonthPerformance) / (weight1 + weight2);
            }
        }
    }
}


text:
module Gifts::Grit
  class Commit

    alias_method :old_message, :message
    alias_method :old_short_message, :short_message

    def message
      Gifts::GritExt.encode! old_message
    end

    def short_message
      Gifts::GritExt.encode! old_short_message
    end
  end
end