//
// TypeHandler.h
//
// $Id: //poco/Main/Data/include/Poco/Data/TypeHandler.h#13 $
//
// Library: Data
// Package: DataCore
// Module:  TypeHandler
//
// Definition of the TypeHandler class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//


#ifndef Data_TypeHandler_INCLUDED
#define Data_TypeHandler_INCLUDED


#include "Poco/Data/Data.h"
#include "Poco/Data/AbstractBinder.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/Data/AbstractPreparator.h"
#include "Poco/Data/Nullable.h"
#include "Poco/Tuple.h"
#include "Poco/AutoPtr.h"
#include "Poco/SharedPtr.h"
#include <cstddef>


namespace Poco {
namespace Data {


class AbstractTypeHandler
	/// Parent class for type handlers. 
	/// The reason for this class is to prevent instantiations of type handlers.
	/// For documentation on type handlers, see TypeHandler class.
{
protected:
	AbstractTypeHandler();
	~AbstractTypeHandler();
	AbstractTypeHandler(const AbstractTypeHandler&);
	AbstractTypeHandler& operator = (const AbstractTypeHandler&);
};


template <class T>
class TypeHandler: public AbstractTypeHandler
	/// Converts Rows to a Type and the other way around. Provide template specializations to support your own complex types.
	///
	/// Take as example the following (simplified) class:
	///    class Person
	///    {
	///    private:
	///        std::string _lastName;
	///        std::string _firstName;
	///        int         _age;
	///        [....] // public set/get methods, a default constructor, optional < operator (for set, multiset) or function operator (for map, multimap)
	///    };
	///
	/// The TypeHandler must provide a custom bind, size, prepare and extract method:
	///    
	///    template <>
	///    class TypeHandler<struct Person>
	///    {
	///    public:
	///        static std::size_t size()
	///        {
	///            return 3; // lastName + firstname + age occupy three columns
	///        }
	///    
	///        static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	///        {
	///            // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
	///            // Note that we advance pos by the number of columns the datatype uses! For string/int this is one.
	///            poco_assert_dbg (pBinder != 0);
	///            TypeHandler<std::string>::bind(pos++, obj.getLastName(), pBinder, dir);
	///            TypeHandler<std::string>::bind(pos++, obj.getFirstName(), pBinder, dir);
	///            TypeHandler<int>::bind(pos++, obj.getAge(), pBinder);
	///        }
	///    
	///        static void prepare(std::size_t pos, const Person& obj, AbstractPreparator* pPreparator)
	///        {
	///            // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
	///            poco_assert_dbg (pPreparator != 0);
	///            TypeHandler<std::string>::prepare(pos++, obj.getLastName(), pPreparator);
	///            TypeHandler<std::string>::prepare(pos++, obj.getFirstName(), pPreparator);
	///            TypeHandler<int>::prepare(pos++, obj.getAge(), pPreparator);
	///        }
	///    
	///        static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt)
	///        {
	///            // defVal is the default person we should use if we encunter NULL entries, so we take the individual fields
	///            // as defaults. You can do more complex checking, ie return defVal if only one single entry of the fields is null etc...
	///            poco_assert_dbg (pExt != 0);
	///            std::string lastName;
	///            std::string firstName;
	///            int age = 0;
	///            // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
	///            TypeHandler<std::string>::extract(pos++, lastName, defVal.getLastName(), pExt);
	///            TypeHandler<std::string>::extract(pos++, firstName, defVal.getFirstName(), pExt);
	///            TypeHandler<int>::extract(pos++, age, defVal.getAge(), pExt);
	///            obj.setLastName(lastName);
	///            obj.setFirstName(firstName);
	///            obj.setAge(age);
	///        }
	///    };
	///
	/// Note that the TypeHandler template specialization must always be declared in the namespace Poco::Data.
	/// Apart from that no further work is needed. One can now use Person with into and use clauses.
{
public:
	static void bind(std::size_t pos, const T& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert_dbg (pBinder != 0);
		pBinder->bind(pos, obj, dir);
	}

	static std::size_t size()
	{
		return 1u;
	}

	static void extract(std::size_t pos, T& obj, const T& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		if (!pExt->extract(pos, obj)) obj = defVal;
	}

	static void prepare(std::size_t pos, T& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		pPreparator->prepare(pos, obj);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};


template <class T>
class TypeHandler<std::deque<T> >: public AbstractTypeHandler
	/// Specialization of type handler for std::deque.
{
public:
	static void bind(std::size_t pos, const std::deque<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert_dbg (pBinder != 0);
		pBinder->bind(pos, obj, dir);
	}

	static std::size_t size()
	{
		return 1u;
	}

	static void extract(std::size_t pos, std::deque<T>& obj, const T& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		if (!pExt->extract(pos, obj))
			obj.assign(obj.size(), defVal);
	}

	static void prepare(std::size_t pos, std::deque<T>& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		pPreparator->prepare(pos, obj);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};


template <class T>
class TypeHandler<std::vector<T> >: public AbstractTypeHandler
	/// Specialization of type handler for std::vector.
{
public:
	static void bind(std::size_t pos, const std::vector<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert_dbg (pBinder != 0);
		pBinder->bind(pos, obj, dir);
	}

	static std::size_t size()
	{
		return 1u;
	}

	static void extract(std::size_t pos, std::vector<T>& obj, const T& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		if (!pExt->extract(pos, obj))
			obj.assign(obj.size(), defVal);
	}

	static void prepare(std::size_t pos, std::vector<T>& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		pPreparator->prepare(pos, obj);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};


template <class T>
class TypeHandler<std::list<T> >: public AbstractTypeHandler
	/// Specialization of type handler for std::list.
{
public:
	static void bind(std::size_t pos, const std::list<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert_dbg (pBinder != 0);
		pBinder->bind(pos, obj, dir);
	}

	static std::size_t size()
	{
		return 1u;
	}

	static void extract(std::size_t pos, std::list<T>& obj, const T& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		if (!pExt->extract(pos, obj))
			obj.assign(obj.size(), defVal);
	}

	static void prepare(std::size_t pos, std::list<T>& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		pPreparator->prepare(pos, obj);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};

template <typename T>
class TypeHandler< Nullable<T> > 
    /// Specialization of type handler for Nullable.
{
public:

    static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir) 
    {
        poco_assert_dbg (pBinder != 0);
        if (obj.isNull()) 
        {
	    pBinder->bind(pos++, Poco::Data::Keywords::null, dir);
        }
        else 
        {
            pBinder->bind(pos++, obj.getValue(), dir);
        }
    }
	
    static void prepare(std::size_t pos, Nullable<T>& obj, AbstractPreparator* pPreparator) 
    {
        poco_assert_dbg (pPreparator != 0);
        if (obj.isNull()) 
        {
            pPreparator->prepare(pos++, (Poco::Any&)Poco::Data::Keywords::null);
        }
        else 
        {
            pPreparator->prepare(pos++, (T&)obj.getValue());
        }
    }

    static std::size_t size() 
    {
        return 1u;
    }

    static void extract(std::size_t pos, Nullable<T>& obj, const Nullable<T>& , AbstractExtractor* pExt) 
    {
        poco_assert_dbg (pExt != 0);
        T value;
    
        if (pExt->extract(pos++, value)) 
        {
	        obj.setValue(value);
        }
        else 
        {
	        obj.setNull(true);
        }
    }

private:

    TypeHandler();
    ~TypeHandler();
    TypeHandler(const TypeHandler&);
    TypeHandler& operator=(const TypeHandler&);
};


/// Poco::Tuple TypeHandler specializations


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14, 
	class T15, 
	class T16, 
	class T17, 
	class T18, 
	class T19>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
		TypeHandler<T15>::bind(pos++, tuple.template get<15>(), pBinder, dir);
		TypeHandler<T16>::bind(pos++, tuple.template get<16>(), pBinder, dir);
		TypeHandler<T17>::bind(pos++, tuple.template get<17>(), pBinder, dir);
		TypeHandler<T18>::bind(pos++, tuple.template get<18>(), pBinder, dir);
		TypeHandler<T19>::bind(pos++, tuple.template get<19>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
		TypeHandler<T15>::prepare(pos++, tuple.template get<15>(), pPreparator);
		TypeHandler<T16>::prepare(pos++, tuple.template get<16>(), pPreparator);
		TypeHandler<T17>::prepare(pos++, tuple.template get<17>(), pPreparator);
		TypeHandler<T18>::prepare(pos++, tuple.template get<18>(), pPreparator);
		TypeHandler<T19>::prepare(pos++, tuple.template get<19>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
		TypeHandler<T15>::extract(pos++, tuple.template get<15>(), defVal.template get<15>(), pExt);
		TypeHandler<T16>::extract(pos++, tuple.template get<16>(), defVal.template get<16>(), pExt);
		TypeHandler<T17>::extract(pos++, tuple.template get<17>(), defVal.template get<17>(), pExt);
		TypeHandler<T18>::extract(pos++, tuple.template get<18>(), defVal.template get<18>(), pExt);
		TypeHandler<T19>::extract(pos++, tuple.template get<19>(), defVal.template get<19>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14, 
	class T15, 
	class T16, 
	class T17, 
	class T18>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
		TypeHandler<T15>::bind(pos++, tuple.template get<15>(), pBinder, dir);
		TypeHandler<T16>::bind(pos++, tuple.template get<16>(), pBinder, dir);
		TypeHandler<T17>::bind(pos++, tuple.template get<17>(), pBinder, dir);
		TypeHandler<T18>::bind(pos++, tuple.template get<18>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
		TypeHandler<T15>::prepare(pos++, tuple.template get<15>(), pPreparator);
		TypeHandler<T16>::prepare(pos++, tuple.template get<16>(), pPreparator);
		TypeHandler<T17>::prepare(pos++, tuple.template get<17>(), pPreparator);
		TypeHandler<T18>::prepare(pos++, tuple.template get<18>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
		TypeHandler<T15>::extract(pos++, tuple.template get<15>(), defVal.template get<15>(), pExt);
		TypeHandler<T16>::extract(pos++, tuple.template get<16>(), defVal.template get<16>(), pExt);
		TypeHandler<T17>::extract(pos++, tuple.template get<17>(), defVal.template get<17>(), pExt);
		TypeHandler<T18>::extract(pos++, tuple.template get<18>(), defVal.template get<18>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14, 
	class T15, 
	class T16, 
	class T17>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
		TypeHandler<T15>::bind(pos++, tuple.template get<15>(), pBinder, dir);
		TypeHandler<T16>::bind(pos++, tuple.template get<16>(), pBinder, dir);
		TypeHandler<T17>::bind(pos++, tuple.template get<17>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
		TypeHandler<T15>::prepare(pos++, tuple.template get<15>(), pPreparator);
		TypeHandler<T16>::prepare(pos++, tuple.template get<16>(), pPreparator);
		TypeHandler<T17>::prepare(pos++, tuple.template get<17>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
		TypeHandler<T15>::extract(pos++, tuple.template get<15>(), defVal.template get<15>(), pExt);
		TypeHandler<T16>::extract(pos++, tuple.template get<16>(), defVal.template get<16>(), pExt);
		TypeHandler<T17>::extract(pos++, tuple.template get<17>(), defVal.template get<17>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14, 
	class T15, 
	class T16>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
		TypeHandler<T15>::bind(pos++, tuple.template get<15>(), pBinder, dir);
		TypeHandler<T16>::bind(pos++, tuple.template get<16>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
		TypeHandler<T15>::prepare(pos++, tuple.template get<15>(), pPreparator);
		TypeHandler<T16>::prepare(pos++, tuple.template get<16>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
		TypeHandler<T15>::extract(pos++, tuple.template get<15>(), defVal.template get<15>(), pExt);
		TypeHandler<T16>::extract(pos++, tuple.template get<16>(), defVal.template get<16>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14, 
	class T15>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
		TypeHandler<T15>::bind(pos++, tuple.template get<15>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
		TypeHandler<T15>::prepare(pos++, tuple.template get<15>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
		TypeHandler<T15>::extract(pos++, tuple.template get<15>(), defVal.template get<15>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13, 
	class T14>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
		TypeHandler<T14>::bind(pos++, tuple.template get<14>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
		TypeHandler<T14>::prepare(pos++, tuple.template get<14>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
		TypeHandler<T14>::extract(pos++, tuple.template get<14>(), defVal.template get<14>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12, 
	class T13>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
		TypeHandler<T13>::bind(pos++, tuple.template get<13>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
		TypeHandler<T13>::prepare(pos++, tuple.template get<13>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
		TypeHandler<T13>::extract(pos++, tuple.template get<13>(), defVal.template get<13>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11, 
	class T12>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
		TypeHandler<T12>::bind(pos++, tuple.template get<12>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
		TypeHandler<T12>::prepare(pos++, tuple.template get<12>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
		TypeHandler<T12>::extract(pos++, tuple.template get<12>(), defVal.template get<12>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10, 
	class T11>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
		TypeHandler<T11>::bind(pos++, tuple.template get<11>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
		TypeHandler<T11>::prepare(pos++, tuple.template get<11>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
		TypeHandler<T11>::extract(pos++, tuple.template get<11>(), defVal.template get<11>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, 
	class T1, 
	class T2, 
	class T3, 
	class T4, 
	class T5, 
	class T6, 
	class T7, 
	class T8, 
	class T9, 
	class T10>
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
		TypeHandler<T10>::bind(pos++, tuple.template get<10>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
		TypeHandler<T10>::prepare(pos++, tuple.template get<10>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
		TypeHandler<T10>::extract(pos++, tuple.template get<10>(), defVal.template get<10>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
		TypeHandler<T9>::bind(pos++, tuple.template get<9>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
		TypeHandler<T9>::prepare(pos++, tuple.template get<9>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
		TypeHandler<T9>::extract(pos++, tuple.template get<9>(), defVal.template get<9>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
		TypeHandler<T8>::bind(pos++, tuple.template get<8>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
		TypeHandler<T8>::prepare(pos++, tuple.template get<8>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
		TypeHandler<T8>::extract(pos++, tuple.template get<8>(), defVal.template get<8>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
		TypeHandler<T7>::bind(pos++, tuple.template get<7>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
		TypeHandler<T7>::prepare(pos++, tuple.template get<7>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, T7, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
		TypeHandler<T7>::extract(pos++, tuple.template get<7>(), defVal.template get<7>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4, class T5, class T6>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
		TypeHandler<T6>::bind(pos++, tuple.template get<6>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
		TypeHandler<T6>::prepare(pos++, tuple.template get<6>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, T5, T6, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
		TypeHandler<T6>::extract(pos++, tuple.template get<6>(), defVal.template get<6>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4, class T5>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, T5, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, T5, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
		TypeHandler<T5>::bind(pos++, tuple.template get<5>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
		TypeHandler<T5>::prepare(pos++, tuple.template get<5>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, T5, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
		TypeHandler<T5>::extract(pos++, tuple.template get<5>(), defVal.template get<5>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3, class T4>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, T4, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, T4, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
		TypeHandler<T4>::bind(pos++, tuple.template get<4>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
		TypeHandler<T4>::prepare(pos++, tuple.template get<4>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, T4, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
		TypeHandler<T4>::extract(pos++, tuple.template get<4>(), defVal.template get<4>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2, class T3>
class TypeHandler<Poco::Tuple<T0, T1, T2, T3, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, T3, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
		TypeHandler<T3>::bind(pos++, tuple.template get<3>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
		TypeHandler<T3>::prepare(pos++, tuple.template get<3>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, T3, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
		TypeHandler<T3>::extract(pos++, tuple.template get<3>(), defVal.template get<3>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1, class T2>
    class TypeHandler<Poco::Tuple<T0, T1, T2, NullTypeList> >
{
public:
        typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, T2, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
		TypeHandler<T2>::bind(pos++, tuple.template get<2>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
		TypeHandler<T2>::prepare(pos++, tuple.template get<2>(), pPreparator);
	}

	static std::size_t size()
	{
	        return static_cast<std::size_t>(Poco::Tuple<T0, T1, T2, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
		TypeHandler<T2>::extract(pos++, tuple.template get<2>(), defVal.template get<2>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0, class T1>
class TypeHandler<Poco::Tuple<T0, T1, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, T1, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
		TypeHandler<T1>::bind(pos++, tuple.template get<1>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
		TypeHandler<T1>::prepare(pos++, tuple.template get<1>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, T1, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
		TypeHandler<T1>::extract(pos++, tuple.template get<1>(), defVal.template get<1>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};


template <class T0>
class TypeHandler<Poco::Tuple<T0, NullTypeList> >
{
public:
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, NullTypeList> >::CONSTREFTYPE TupleConstRef;
	typedef typename Poco::TypeWrapper<Poco::Tuple<T0, NullTypeList> >::REFTYPE      TupleRef;

	static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		poco_assert (pBinder != 0);
		TypeHandler<T0>::bind(pos++, tuple.template get<0>(), pBinder, dir);
	}

	static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparator* pPreparator)
	{
		poco_assert (pPreparator != 0);
		TypeHandler<T0>::prepare(pos++, tuple.template get<0>(), pPreparator);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(Poco::Tuple<T0, NullTypeList>::length);
	}

	static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, 
		AbstractExtractor* pExt)
	{
		poco_assert (pExt != 0);
		TypeHandler<T0>::extract(pos++, tuple.template get<0>(), defVal.template get<0>(), pExt);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator=(const TypeHandler&);
};



template <class K, class V>
class TypeHandler<std::pair<K, V> >: public AbstractTypeHandler
{
public:
	static void bind(std::size_t pos, const std::pair<K, V>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		TypeHandler<K>::bind(pos, obj.first, pBinder, dir);
		pos += TypeHandler<K>::size();
		TypeHandler<V>::bind(pos, obj.second, pBinder, dir);
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(TypeHandler<K>::size() + TypeHandler<V>::size());
	}

	static void extract(std::size_t pos, std::pair<K, V>& obj, const std::pair<K, V>& defVal, AbstractExtractor* pExt)
	{
		TypeHandler<K>::extract(pos, obj.first, defVal.first, pExt);
		pos += TypeHandler<K>::size();
		TypeHandler<V>::extract(pos, obj.second, defVal.second, pExt);
	}

	static void prepare(std::size_t pos, std::pair<K, V>& obj, AbstractPreparator* pPreparator)
	{
		TypeHandler<K>::prepare(pos, obj.first, pPreparator);
		pos += TypeHandler<K>::size();
		TypeHandler<V>::prepare(pos, obj.second, pPreparator);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};


template <class T>
class TypeHandler<Poco::AutoPtr<T> >: public AbstractTypeHandler
	/// Specialization of type handler for Poco::AutoPtr
{
public:
	static void bind(std::size_t pos, const Poco::AutoPtr<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		// *obj will trigger a nullpointer exception if empty: this is on purpose
		TypeHandler<T>::bind(pos, *obj, pBinder, dir); 
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(TypeHandler<T>::size());
	}

	static void extract(std::size_t pos, Poco::AutoPtr<T>& obj, const Poco::AutoPtr<T>& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		
		obj = Poco::AutoPtr<T>(new T());
		if (defVal)
			TypeHandler<T>::extract(pos, *obj, *defVal, pExt);
		else
			TypeHandler<T>::extract(pos, *obj, *obj, pExt);
	}

	static void prepare(std::size_t pos, Poco::AutoPtr<T>& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		if (!obj)
			obj = new T();
		TypeHandler<T>::prepare(pos, *obj, pPreparator);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};



template <class T>
class TypeHandler<Poco::SharedPtr<T> >: public AbstractTypeHandler
	/// Specialization of type handler for Poco::SharedPtr
{
public:
	static void bind(std::size_t pos, const Poco::SharedPtr<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
	{
		// *obj will trigger a nullpointer exception if empty: this is on purpose
		TypeHandler<T>::bind(pos, *obj, pBinder, dir); 
	}

	static std::size_t size()
	{
		return static_cast<std::size_t>(TypeHandler<T>::size());
	}

	static void extract(std::size_t pos, Poco::SharedPtr<T>& obj, const Poco::SharedPtr<T>& defVal, AbstractExtractor* pExt)
	{
		poco_assert_dbg (pExt != 0);
		
		obj = Poco::SharedPtr<T>(new T());
		if (defVal)
			TypeHandler<T>::extract(pos, *obj, *defVal, pExt);
		else
			TypeHandler<T>::extract(pos, *obj, *obj, pExt);
	}

	static void prepare(std::size_t pos, Poco::SharedPtr<T>& obj, AbstractPreparator* pPreparator)
	{
		poco_assert_dbg (pPreparator != 0);
		if (!obj)
			obj = new T();
		TypeHandler<T>::prepare(pos, *obj, pPreparator);
	}

private:
	TypeHandler(const TypeHandler&);
	TypeHandler& operator = (const TypeHandler&);
};


} } // namespace Poco::Data


#endif // Data_TypeHandler_INCLUDED
