<?php session_start();
ob_start();
$sql_username = "";
$sql_password = "";
$sql_host = "";
$sql_dbname = "";
$config['mail'] = ""; //Jouw e-mailadres
$config['website'] = ""; //De url naar je website
mysql_connect($sql_host, $sql_username, $sql_password);
mysql_select_db($sql_dbname);
function keygen($i)
    {
        $alfabet = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'), range('0', '9'));
        $actkey = "";
        while(strlen($actkey) < $i)
            {
                $actkey .= $alfabet[array_rand($alfabet)];
            }
        return($actkey);
    }
function mysql_is_unique($value, $table, $field)
    {
        $sql = "SELECT ".$field." FROM ".$table." WHERE ".$field." LIKE '".$value."' LIMIT 1";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        if(mysql_num_rows($res) > 0)
            {
                return false;
            }
        else
            {
                return true;
            }
    }
function is_unieke_naam_in_groep($naam, $gid)
    {
        $sql = "SELECT id FROM mensen WHERE naam LIKE '".$naam."' AND groep_id = ".$gid." LIMIT 1";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        if(mysql_num_rows($res) > 0)
            {
                return false;
            }
        else
            {
                return true;
            }
    }
function echo_mysql_error($sql)
    {
        echo '

MySQL error
: '.mysql_error().'

Query:

'.$sql.'
';
        exit();
    }
function form_login($username = null, $gid = null, $code = null)
    {
        $sql = "SELECT id, naam FROM groepen ORDER BY naam";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        echo '
			<form method="post" action="login.php">
				<fieldset>
					<legend>Inloggen</legend>

Groepsnaam

					<select name="groepsnaam">
	                    <option value="">Maak je keuze...</option>';
	        while($row = mysql_fetch_assoc($res))
	            {
	                 if($gid == $row['id'])
	                     {
	                        echo '
	                    <option value="'.$row['id'].'" selected="selected">'.$row['naam'].'</option>';
	                    }
	                else
	                    {
	                        echo '
	                    <option value="'.$row['id'].'">'.$row['naam'].'</option>';
	                    }
	            }
	        echo '
	                </select>

	                Maak een nieuwe groep aan

Naam

					<input type="text" name="gebruikersnaam" value="'.$username.'" />

Inlogcode

					<input type="password" name="inlogcode" value="'.$code.'" />

<input type="submit" value="Log in" />

				</fieldset>
			</form>';
    }
function begin_pagina()
    {
        echo '
			<!DOCTYPE html>
			<meta charset="utf-8">
			<title>Lootjes trekken</title>
			<link rel="stylesheet" type="text/css" href="/static/css/universal.css" media="all">
			<link rel="stylesheet" type="text/css" href="/static/css/default.css" media="all">
			<link rel="stylesheet" type="text/css" href="/static/css/custom.css" media="all">

De Lootjestrekmachine

		';
    }
function einde_pagina()
    {
         echo '

© 2006-'.date("Y").', powered by de Lootjestrekmachine, scripting door Herjan Treurniet, revisie door Ellen O\'Neill, Universal CSS van Andy Clarke. Aan deze website kunnen geen rechten ontleend worden. De makers van deze website zijn niet aansprakelijk voor de gevolgen van het gebruik van deze website. De diensten aangeboden op deze site zijn volkomen gratis, verwacht dan ook niet al te veel service.

		';
        ob_end_flush();
    }
function _make_url_clickable_cb($matches) {
	$ret = '';
	$url = $matches[2];

	if ( empty($url) )
		return $matches[0];
	// removed trailing [.,;:] from URL
	if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
		$ret = substr($url, -1);
		$url = substr($url, 0, strlen($url)-1);
	}
	return $matches[1] . "$url" . $ret;
}

function _make_web_ftp_clickable_cb($matches) {
	$ret = '';
	$dest = $matches[2];
	$dest = 'http://' . $dest;

	if ( empty($dest) )
		return $matches[0];
	// removed trailing [,;:] from URL
	if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
		$ret = substr($dest, -1);
		$dest = substr($dest, 0, strlen($dest)-1);
	}
	return $matches[1] . "$dest" . $ret;
}

function _make_email_clickable_cb($matches) {
	$email = $matches[2] . '@' . $matches[3];
	return $matches[1] . "$email";
}

function make_clickable($ret) {
	$ret = ' ' . $ret;
	// in testing, using arrays here was found to be faster
	$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_url_clickable_cb', $ret);
	$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
	$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);

	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
	$ret = preg_replace("#(]+?>|>))]+?>([^>]+?)#i", "$1$3", $ret);
	$ret = trim($ret);
	return $ret;
}
?>

<?php session_start();
ob_start();
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
$sql_username = "";
$sql_password = "";
$sql_host = "";
$sql_dbname = "";
$config['mail'] = ""; //Jouw e-mailadres
$config['website'] = ""; //De url naar je website
mysql_connect($sql_host, $sql_username, $sql_password);
mysql_select_db($sql_dbname);
function keygen($i)
    {
        $alfabet = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'), range('0', '9'));
        $actkey = "";
        while(strlen($actkey) < $i)
            {
                $actkey .= $alfabet[array_rand($alfabet)];
            }
        return($actkey);
    }
function mysql_is_unique($value, $table, $field)
    {
        $sql = "SELECT ".$field." FROM ".$table." WHERE ".$field." LIKE '".$value."' LIMIT 1";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        if(mysql_num_rows($res) > 0)
            {
                return false;
            }
        else
            {
                return true;
            }
    }
function is_unieke_naam_in_groep($naam, $gid)
    {
        $sql = "SELECT id FROM mensen WHERE naam LIKE '".$naam."' AND groep_id = ".$gid." LIMIT 1";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        if(mysql_num_rows($res) > 0)
            {
                return false;
            }
        else
            {
                return true;
            }
    }
function echo_mysql_error($sql)
    {
        echo '

MySQL error
: '.mysql_error().'

Query:

'.$sql.'
';
        exit();
    }
function form_login($username = null, $gid = null, $code = null)
    {
        $sql = "SELECT id, naam FROM groepen ORDER BY naam";
        $res = mysql_query($sql) or echo_mysql_error($sql);
        echo '
			<form method="post" action="login.php">
				<fieldset>
					<legend>Inloggen</legend>

Groepsnaam

					<select name="groepsnaam">
	                    <option value="">Maak je keuze...</option>';
	        while($row = mysql_fetch_assoc($res))
	            {
	                 if($gid == $row['id'])
	                     {
	                        echo '
	                    <option value="'.$row['id'].'" selected="selected">'.$row['naam'].'</option>';
	                    }
	                else
	                    {
	                        echo '
	                    <option value="'.$row['id'].'">'.$row['naam'].'</option>';
	                    }
	            }
	        echo '
	                </select>

	                Maak een nieuwe groep aan

Naam

					<input type="text" name="gebruikersnaam" value="'.$username.'" />

Inlogcode

					<input type="password" name="inlogcode" value="'.$code.'" />

<input type="submit" value="Log in" />

				</fieldset>
			</form>';
    }
function begin_pagina()
    {
        echo '
			<!DOCTYPE html>
			<meta charset="utf-8">
			<title>Lootjes trekken</title>
			<link rel="stylesheet" type="text/css" href="/static/css/universal.css" media="all">
			<link rel="stylesheet" type="text/css" href="/static/css/default.css" media="all">
			<link rel="stylesheet" type="text/css" href="/static/css/custom.css" media="all">

De Lootjestrekmachine

		';
    }
function einde_pagina()
    {
         echo '

© 2006-'.date("Y").', powered by de Lootjestrekmachine, scripting door Herjan Treurniet, revisie door Ellen O\'Neill, Universal CSS van Andy Clarke. Aan deze website kunnen geen rechten ontleend worden. De makers van deze website zijn niet aansprakelijk voor de gevolgen van het gebruik van deze website. De diensten aangeboden op deze site zijn volkomen gratis, verwacht dan ook niet al te veel service.

		';
        ob_end_flush();
    }
function _make_url_clickable_cb($matches) {
	$ret = '';
	$url = $matches[2];

	if ( empty($url) )
		return $matches[0];
	// removed trailing [.,;:] from URL
	if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
		$ret = substr($url, -1);
		$url = substr($url, 0, strlen($url)-1);
	}
	return $matches[1] . "$url" . $ret;
}

function _make_web_ftp_clickable_cb($matches) {
	$ret = '';
	$dest = $matches[2];
	$dest = 'http://' . $dest;

	if ( empty($dest) )
		return $matches[0];
	// removed trailing [,;:] from URL
	if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
		$ret = substr($dest, -1);
		$dest = substr($dest, 0, strlen($dest)-1);
	}
	return $matches[1] . "$dest" . $ret;
}

function _make_email_clickable_cb($matches) {
	$email = $matches[2] . '@' . $matches[3];
	return $matches[1] . "$email";
}

function make_clickable($ret) {
	$ret = ' ' . $ret;
	// in testing, using arrays here was found to be faster
	$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_url_clickable_cb', $ret);
	$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
	$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);

	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
	$ret = preg_replace("#(]+?>|>))]+?>([^>]+?)#i", "$1$3", $ret);
	$ret = trim($ret);
	return $ret;
}
?>


require 'selectable_attr_rails/helpers/abstract_selection_helper'
module SelectableAttrRails::Helpers
  module CheckBoxGroupHelper
    class Builder < SelectableAttrRails::Helpers::AbstractSelectionBuilder

      def initialize(object, object_name, method, options, template)
        super(object, object_name, method, options, template)
        @entry_hash_array ||= enum_hash_array_from_object
        @param_name = "#{@base_name}_ids"
        @check_box_options = @options.delete(:check_box) || {}
      end

      def each(&block)
        @entry_hash_array.each do |entry_hash|
          @entry_hash= entry_hash
          @tag_value = @entry_hash[:id].to_s.gsub(/\s/, "_").gsub(/\W/, "")
          @check_box_id = "#{@object_name}_#{@param_name}_#{@tag_value}"
          yield(self)
        end
      end

      def check_box(options = nil)
        options = update_options({
            :id => @check_box_id, :type => 'checkbox', :value => @tag_value,
            :name => "#{@object_name}[#{@param_name}][]"
          }, @check_box_options, options)
        options[:checked] = 'checked' if @entry_hash[:select]
        @template.content_tag("input", nil, options)
      end

      def label(text = nil, options = nil)
        @template.content_tag("label", text || @entry_hash[:name],
          update_options({:for => @check_box_id}, options))
      end
    end

    module Base
      def check_box_group(object_name, method, options = nil, &block)
        object = (options || {})[:object] || instance_variable_get("@#{object_name}")
        builder = Builder.new(object, object_name, method, options, @template)
        if block_given?
          yield(builder)
          return nil
        else
          result = ''
          builder.each do
            result << builder.check_box
            result << ' '
            result << builder.label
            result << ' '
          end
          return result
        end
      end
    end

    module FormBuilder
      def check_box_group(method, options = nil, &block)
        @template.check_box_group(@object_name, method,
          (options || {}).merge(:object => @object), &block)
      end
    end
  end
end

require 'selectable_attr_rails/helpers/abstract_selection_helper'
module SelectableAttrRails::Helpers
  module CheckBoxGroupHelper
    class Builder < SelectableAttrRails::Helpers::AbstractSelectionBuilder

      def initialize(object, object_name, method, options, template)
        super(object, object_name, method, options, template)
        @entry_hash_array ||= enum_hash_array_from_object
        @param_name = "#{@base_name}_ids"
        @check_box_options = @options.delete(:check_box) || {}
      end

      def each(&block)
        @entry_hash_array.each do |entry_hash|
          @entry_hash= entry_hash
          @tag_value = @entry_hash[:id].to_s.gsub(/\s/, "_").gsub(/\W/, "")
          @check_box_id = "#{@object_name}_#{@param_name}_#{@tag_value}"
          yield(self)
        end
      end

      def check_box(options = nil)
        options = update_options({
            :id => @check_box_id, :type => 'checkbox', :value => @tag_value,
            :name => "#{@object_name}[#{@param_name}][]"
          }, @check_box_options, options)
        options[:checked] = 'checked' if @entry_hash[:select]
        @template.content_tag("input", nil, options)
      end

      def label(text = nil, options = nil)
        @template.content_tag("label", text || @entry_hash[:name],
          update_options({:for => @check_box_id}, options))
      end
    end

    module Base
      def check_box_group(object_name, method, options = nil, &block)
        object = (options || {})[:object] || instance_variable_get("@#{object_name}")
        builder = Builder.new(object, object_name, method, options, self)
        if block_given?
          yield(builder)
          return nil
        else
          result = ''
          builder.each do
            result << builder.check_box
            result << ' '
            result << builder.label
            result << ' '
          end
          return result.respond_to?(:html_safe) ? result.html_safe : result
        end
      end
    end

    module FormBuilder
      def check_box_group(method, options = nil, &block)
        @template.check_box_group(@object_name, method,
          (options || {}).merge(:object => @object), &block)
      end
    end
  end
end


/**
 * @author Eli Fox-Epstein
 */
 public class TuringMachineWithNoSemicolons {
    /* ARGS:
     *  0: tape
     *  1: state
     *  2: current index
     *  3: transition table (prefix "ABCDE" means at state A, if read a B, move C, write D, go to state E)
     *  4: reject state
     *  5: accept state
     *
     * Example use: a turing machine that recognizes the languages of words of the form: 0^jELI
     *
     * One way to write a machine for this is with the following rules:
     *      at A, if 0, move R, write _, goto A
     *      at A, if E, move R, write _, goto B
     *      at B, if L, move R, write _, goto C
     *      at C, if I, move R, write _, goto +
     * A test case:
     *      java TuringMachineWithNoSemicolons 00000ELI A 0 A0R_AAER_BBLR_CCIR_+ - +
     *
     * This machine will not halt on most inputs.
     */
    public static void main(String[] args) {
        while(!args[1].equals(args[4]) && !args[1].equals(args[5])){
            if((args[1] + args[0].charAt(Integer.parseInt(args[2]))).equals(args[3].substring(0,2))){

                // Write
                if((        args[0] = args[0].substring(0, Integer.parseInt(args[2])) +
                                      args[3].charAt(3) +
                                      args[0].substring(Integer.parseInt(args[2])+1, args[0].length())
                ) == ""){}

                if(args[3].charAt(2) == 'L'){
                    if((    args[2] = (Integer.parseInt(args[2])-1) + ""            ) != ""){}
                }else{
                    if((    args[2] = (Integer.parseInt(args[2])+1) + ""            ) != ""){}
                }

                // Update current state
                if((        args[1] = args[3].charAt(4) + ""                        ) != ""){}

            }else{
                // Cycle transition table
                if((args[3] = args[3].substring(5, args[3].length()) + args[3].substring(0,5)) != ""){}
            }
        }
        if(args[1].equals(args[4])){
            if(System.out.printf("REJECT: " + args[0]) == null){}
        }else if(System.out.printf("ACCEPT: " + args[0]) == null){}
    }
}

/**
 * @author Eli Fox-Epstein
 */
 public class TuringMachineWithNoSemicolons {
    /* ARGS:
     *  0: tape
     *  1: state
     *  2: current index
     *  3: transition table (prefix "ABCDE" means at state A, if read a B, move C, write D, go to state E)
     *  4: reject state
     *  5: accept state
     *
     * Example use: a turing machine that recognizes the languages of words of the form: 0^jELI
     *
     * One way to write a machine for this is with the following rules:
     *      at A, if 0, move R, write _, goto A
     *      at A, if E, move R, write _, goto B
     *      at B, if L, move R, write _, goto C
     *      at C, if I, move R, write _, goto +
     * A test case:
     *      java TuringMachineWithNoSemicolons 00000ELI A 0 A0R_AAER_BBLR_CCIR_+ - +
     *
     * This machine will not halt on most inputs.
     * TODO: use stream() api with lambda expressions.
     */
    public static void main(String[] args) {
        while(!args[1].equals(args[4]) && !args[1].equals(args[5])){
            if((args[1] + args[0].charAt(Integer.parseInt(args[2]))).equals(args[3].substring(0,2))){

                // Write
                if((        args[0] = args[0].substring(0, Integer.parseInt(args[2])) +
                                      args[3].charAt(3) +
                                      args[0].substring(Integer.parseInt(args[2])+1, args[0].length())
                ) == ""){}

                if(args[3].charAt(2) == 'L'){
                    if((    args[2] = (Integer.parseInt(args[2])-1) + ""            ) != ""){}
                }else{
                    if((    args[2] = (Integer.parseInt(args[2])+1) + ""            ) != ""){}
                }

                // Update current state
                if((        args[1] = args[3].charAt(4) + ""                        ) != ""){}

            }else{
                // Cycle transition table
                if((args[3] = args[3].substring(5, args[3].length()) + args[3].substring(0,5)) != ""){}
            }
        }
        if(args[1].equals(args[4])){
            if(System.out.printf("REJECT: " + args[0]) == null){}
        }else if(System.out.printf("ACCEPT: " + args[0]) == null){}
    }
}


//
//  Copyright (c) 2009, Tweak Software
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions
//  are met:
//
//     * Redistributions of source code must retain the above
//       copyright notice, this list of conditions and the following
//       disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials
//       provided with the distribution.
//
//     * Neither the name of the Tweak Software nor the names of its
//       contributors may be used to endorse or promote products
//       derived from this software without specific prior written
//       permission.
//
//  THIS SOFTWARE IS PROVIDED BY Tweak Software ''AS IS'' AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//  ARE DISCLAIMED. IN NO EVENT SHALL Tweak Software BE LIABLE FOR
//  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
//  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
//  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
//  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//  DAMAGE.
//

#include <sstream>
#include "gtoWriter.h"

namespace PyGto {
using namespace std;

// *****************************************************************************
// We start with a few utility functions...
// *****************************************************************************

// *****************************************************************************
// Properly deallocate the instance-specific stuff-holder object
void gtoWriter_PyObject_dealloc( PyObject *self )
{
    assert( self != NULL );
    gtoWriter_PyObject *gwSelf = (gtoWriter_PyObject *)self;
    delete gwSelf->m_writer;
    delete gwSelf->m_propertyNames;
    PyObject_DEL( self );
}

// *****************************************************************************
// Flatten a tuple or list into a C array of any type using the converter
// supplied.  'start' is used internally for recursive purposes.  Returns
// the number of items in the C array.
template<typename T> int flatten( PyObject *object,
                                  T *data,
                                  int maxItems,
                                  const char *expectedTypeStr,
                                  T (*converter)(PyObject *),
                                  bool start = true )
{
    static int pos;
    if( start )
    {
        pos = 0;
    }
    if( pos > maxItems )
    {
        return pos;
    }

    // If we come across a class instance, do we know what to do with it?
    if( PyInstance_Check( object ) )
    {
        string classname( PyTypeName( object ) );

        // If we know what it is, convert it to something useful
        if( classname == "mat3" || classname == "mat4" )
        {
            // mat3 and mat4 convert easily to a list
            PyObject *tmp = PyObject_GetAttrString( object, "mlist" );
            Py_INCREF( tmp );
            object = tmp;

        }
        else if( classname == "vec3" || classname == "vec4" )
        {
            // vec3 and vec4 have no handy .toList() method, so we have
            // to do it the 'hard way'...
            PyObject *tmp;
            classname == "vec3" ? tmp = PyTuple_New(3) : tmp = PyTuple_New(4);

            PyObject *x = PyObject_GetAttrString( object, "x" );
            Py_INCREF( x );
            PyObject *y = PyObject_GetAttrString( object, "y" );
            Py_INCREF( y );
            PyObject *z = PyObject_GetAttrString( object, "z" );
            Py_INCREF( z );
            PyTuple_SetItem( tmp, 0, x );
            PyTuple_SetItem( tmp, 1, y );
            PyTuple_SetItem( tmp, 2, z );
            if( classname == "vec4" )
            {
                PyObject *w = PyObject_GetAttrString( object, "w" );
                Py_INCREF( w );
                PyTuple_SetItem( tmp, 3, w );
            }
            object = tmp;
        }
        else if( classname == "quat" )
        {
            // quat has no handy .toList() method either...
            PyObject *tmp = PyTuple_New(4);

            PyObject *w = PyObject_GetAttrString( object, "w" );
            Py_INCREF( w );
            PyObject *x = PyObject_GetAttrString( object, "x" );
            Py_INCREF( x );
            PyObject *y = PyObject_GetAttrString( object, "y" );
            Py_INCREF( y );
            PyObject *z = PyObject_GetAttrString( object, "z" );
            Py_INCREF( z );
            PyTuple_SetItem( tmp, 0, w );
            PyTuple_SetItem( tmp, 1, x );
            PyTuple_SetItem( tmp, 2, y );
            PyTuple_SetItem( tmp, 3, z );
            object = tmp;
        }
        else
        {
            // Otherwise, barf on it
            PyErr_Format( gtoError(), "Can't handle '%s' class data directly."
                                      "  Convert it to a tuple or list first.",
                            classname.c_str() );
            return -1;
        }
    }

    // Put atoms directly into the buffer, and recurse on more complex types
    for( int i = 0; i < PySequence_Size( object ); ++i )
    {
        PyObject *item = PySequence_GetItem( object, i );
        if( PyTuple_Check( item )
           || PyList_Check( item )
           || PyInstance_Check( item ) )
        {
            flatten( item, data, maxItems, expectedTypeStr, converter, false );
        }
        else
        {
            // Add the atom to the buffer and move on
            data[pos] = converter( item );
            if( PyErr_Occurred() )
            {
                if( ! PyErr_ExceptionMatches( PyExc_TypeError ) )
                {
                    // This is something other than a type error, so
                    // this will cause a Python traceback later...
                    return -1;
                }
                // Data of a type not handled by the converter
                PyErr_Format( gtoError(), "Expected data of type '%s', but "
                                          "got '%s'", expectedTypeStr,
                                                      PyTypeName( item ) );
                return -1;
            }
            pos++;
            if( pos > maxItems )
            {
                return pos;
            }
        }
    }

    return pos;
}

// *****************************************************************************
// The next several functions implement the methods on the Python gto.Writer
// class.
// *****************************************************************************

// *****************************************************************************
// gto.Writer class constructor. Does nothing, but is required anyway
PyObject *gtoWriter_init( PyObject *_self, PyObject *args )
{
    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.open( filename )
PyObject *gtoWriter_open( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *filename;
    Gto::Writer::FileType filemode = Gto::Writer::CompressedGTO;

    if( ! PyArg_ParseTuple( args, "Os|i:gtoWriter_open", &self, &filename,
                                                         &filemode ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Create a new python writer object and add it to this instance's
    // dictionary
    gtoWriter_PyObject *writer = PyObject_NEW( gtoWriter_PyObject,
                                               &gtoWriter_PyObjectType );
    writer->m_writer = new Gto::Writer();
    writer->m_propCount = 0;
    writer->m_beginDataCalled = false;
    writer->m_objectDef = false;
    writer->m_componentDef = false;
    writer->m_propertyNames = new vector<string>;

    PyDict_SetItemString( self->in_dict, "__writerEngine", (PyObject *)writer );

    // Ask the writer to open the given file
    if( ! writer->m_writer->open( filename, filemode ) )
    {
        PyErr_Format( gtoError(), "Unable to open specified file: %s",
                      filename );
        return NULL;
    }

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.close()
PyObject *gtoWriter_close( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    if( ! PyArg_ParseTuple( args, "O:gtoWriter_close", &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Close the file
    writer->m_writer->close();

    // Remove the writer from the class dictionary
    PyDict_DelItemString( self->in_dict, "__writerEngine" );
    Py_DECREF( writer );

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.beginObject( name, protocol, protocolVersion )
PyObject *gtoWriter_beginObject( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    char *protocol;
    unsigned int protocolVersion;

    if( ! PyArg_ParseTuple( args, "Ossi:gtoWriter_beginObject",
                            &self, &name, &protocol, &protocolVersion ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == true )
    {
        PyErr_SetString( gtoError(), "Can't nest object declarations" );
        return NULL;
    }
    if( writer->m_beginDataCalled == true )
    {
        PyErr_SetString( gtoError(), "Once beginData is called, no new "
                                     "objects can be declared" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginObject( name, protocol, protocolVersion );
    writer->m_objectDef = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.endObject()
PyObject *gtoWriter_endObject( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endObject",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false )
    {
        PyErr_SetString( gtoError(), "endObject called before beginObject" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endObject();
    writer->m_objectDef = false;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.beginComponent( name, interp, flags )
PyObject *gtoWriter_beginComponent( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    char *interp = "";
    int flags = 0;

    // Try GTOv2 prototype first...
    if( ! PyArg_ParseTuple( args, "Os|i:gtoWriter_beginComponent",
                            &self, &name, &flags ) )
    {
        PyErr_Clear();
        // If that doesn't work, try the GTOv3 prototype
        if( ! PyArg_ParseTuple( args, "Oss|i:gtoWriter_beginComponent",
                                &self, &name, &interp, &flags ) )
        {
            // Invalid parameters, let Python do a stack trace
            return NULL;
        }
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false )
    {
        PyErr_SetString( gtoError(), "Components can only exist inside object "
                                     "blocks" );
        return NULL;
    }
    if( writer->m_componentDef == true )
    {
        PyErr_SetString( gtoError(), "Can't nest component declarations" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginComponent( name, interp, flags );
    writer->m_componentDef = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.endComponent()
PyObject *gtoWriter_endComponent( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endComponent",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_componentDef == false )
    {
        PyErr_SetString( gtoError(), "endComponent called before "
                                     "beginComponent" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endComponent();
    writer->m_componentDef = false;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.property( name, type, numElements, width, interp )
PyObject *gtoWriter_property( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    int type;
    int numElements;
    int width = 1;
    char *interp = "";

    if( ! PyArg_ParseTuple( args, "Osii|is:gtoWriter_property",
                            &self, &name, &type, &numElements,
                            &width, &interp ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false || writer->m_componentDef == false )
    {
        PyErr_SetString( gtoError(), "Properties can only exist inside "
                                     "object/component blocks" );
        return NULL;
    }

    // Store name for later dumbassness checking in propertyData()
    writer->m_propertyNames->push_back( name );

    // Make it so
    writer->m_writer->property( name,
                                (Gto::DataType)type,
                                numElements,
                                width,
                                interp );

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.intern( string | tuple | list )
PyObject *gtoWriter_intern( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    PyObject *data;

    if( ! PyArg_ParseTuple( args, "OO:gtoWriter_intern",
                            &self, &data ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Handle a single string
    if( PyString_Check( data ) )
    {
        char *str = PyString_AsString( data );
        writer->m_writer->intern( str );
    }
    // Handle a bunch of strings all at once
    else if( PySequence_Check( data ) )
    {
        for( int i = 0; i < PySequence_Size( data ); ++i )
        {
            PyObject *pstr = PySequence_GetItem( data, i );
            if( ! PyString_Check( pstr ) )
            {
                PyErr_SetString( gtoError(), "Non-string in sequence" );
                return NULL;
            }
            char *str = PyString_AsString( pstr );
            writer->m_writer->intern( str );
        }
    }
    // We can't handle what we were given
    else
    {
        PyErr_SetString( gtoError(), "intern requires a string or a "
                                     "sequence of strings" );
        return NULL;
    }

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.lookup( string )
PyObject *gtoWriter_lookup( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *str;

    if( ! PyArg_ParseTuple( args, "Os:gtoWriter_lookup",
                            &self, &str ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_beginDataCalled == false )
    {
        PyErr_SetString( gtoError(), "lookup() cannot be used until "
                                     "beginData() is called" );
        return NULL;
    }

    // Make it so
    PyObject *strId_PyObj = PyInt_FromLong( writer->m_writer->lookup( str ) );

    Py_INCREF( strId_PyObj );
    return strId_PyObj;
}

// *****************************************************************************
// implements gto.Writer.beginData()
PyObject *gtoWriter_beginData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_beginData",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_writer->properties().size() == 0 )
    {
        PyErr_SetString( gtoError(), "There are no properties to write" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginData();
    writer->m_beginDataCalled = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.endData()
PyObject *gtoWriter_endData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endData",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_beginDataCalled == false )
    {
        PyErr_SetString( gtoError(), "endData called before beginData" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endData();

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.propertyData( data )
PyObject *gtoWriter_propertyData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    PyObject *rawdata;

    if( ! PyArg_ParseTuple( args, "OO:gtoWriter_propertyData",
                            &self, &rawdata ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( ! writer->m_beginDataCalled )
    {
        PyErr_SetString( gtoError(), "propertyData called before beginData" );
        return NULL;
    }

    // If we're handed a single value, tuple-ize it for the code below
    if( PyInt_Check( rawdata )
        || PyFloat_Check( rawdata )
        || PyString_Check( rawdata ) )
    {
        PyObject *tmp = PyTuple_New( 1 );
        PyTuple_SetItem( tmp, 0, rawdata );
        Py_DECREF( rawdata );
        rawdata = tmp;
    }

    // Get a handle to the property definition for the current property
    // and do some sanity checking
    Gto::PropertyHeader prop;
    prop = writer->m_writer->properties()[writer->m_propCount];
    if( writer->m_propCount >= writer->m_writer->properties().size() )
    {
        PyErr_SetString( gtoError(), "Undeclared data." );
        return NULL;
    }

    const char *currentPropName = (*writer->m_propertyNames)[writer->m_propCount].c_str();

    // Determine how many elements we have in the data
    int dataSize = prop.size * prop.width;

    // Write that data!
    if( prop.type == Gto::Int )
    {
        int *data = new int[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "int", PyInt_AsInt );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }

    if( prop.type == Gto::Float )
    {
        float *data = new float[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "float",
                                PyFloat_AsFloat );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Double )
    {
        double *data = new double[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "double",
                                PyFloat_AsDouble );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Short )
    {
        unsigned short *data = new unsigned short[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "short",
                                PyInt_AsShort );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Byte )
    {
        unsigned char *data = new unsigned char[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "byte",
                                PyInt_AsByte );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::String )
    {
        char **strings = new char *[dataSize];
        int numItems = flatten( rawdata, strings, dataSize, "string",
                                PyString_AsString );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, prop.width,
                          numItems );
            return NULL;
        }

        int *data = new int[dataSize];
        for( int i = 0; i < numItems; ++i )
        {
            data[i] = writer->m_writer->lookup( strings[i] );
            if( data[i] == -1 )
            {
                PyErr_Format( gtoError(),
                       "'%s' needs to be \"interned\" before it can "
                       "be used as data in property #%d",
                       strings[i], writer->m_propCount );
                return NULL;
            }
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] strings;
        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }

    PyErr_Format( gtoError(), "Undefined property type: %d  in property '%s'",
                     prop.type, currentPropName );
    return NULL;
}

}; // End namespace PyGto

//
//  Copyright (c) 2009, Tweak Software
//  All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions
//  are met:
//
//     * Redistributions of source code must retain the above
//       copyright notice, this list of conditions and the following
//       disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials
//       provided with the distribution.
//
//     * Neither the name of the Tweak Software nor the names of its
//       contributors may be used to endorse or promote products
//       derived from this software without specific prior written
//       permission.
//
//  THIS SOFTWARE IS PROVIDED BY Tweak Software ''AS IS'' AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//  ARE DISCLAIMED. IN NO EVENT SHALL Tweak Software BE LIABLE FOR
//  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
//  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
//  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
//  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//  DAMAGE.
//

#include <sstream>
#include "gtoWriter.h"

namespace PyGto {
using namespace std;

// *****************************************************************************
// We start with a few utility functions...
// *****************************************************************************

// *****************************************************************************
// Properly deallocate the instance-specific stuff-holder object
void gtoWriter_PyObject_dealloc( PyObject *self )
{
    assert( self != NULL );
    gtoWriter_PyObject *gwSelf = (gtoWriter_PyObject *)self;
    delete gwSelf->m_writer;
    delete gwSelf->m_propertyNames;
    PyObject_DEL( self );
}

// *****************************************************************************
// Flatten a tuple or list into a C array of any type using the converter
// supplied.  'start' is used internally for recursive purposes.  Returns
// the number of items in the C array.
template<typename T> int flatten( PyObject *object,
                                  T *data,
                                  int maxItems,
                                  const char *expectedTypeStr,
                                  T (*converter)(PyObject *),
                                  bool start = true )
{
    static int pos;
    if( start )
    {
        pos = 0;
    }
    if( pos > maxItems )
    {
        return pos;
    }

    // If we come across a class instance, do we know what to do with it?
    if( PyInstance_Check( object ) )
    {
        string classname( PyTypeName( object ) );

        // If we know what it is, convert it to something useful
        if( classname == "mat3" || classname == "mat4" )
        {
            // mat3 and mat4 convert easily to a list
            PyObject *tmp = PyObject_GetAttrString( object, "mlist" );
            Py_INCREF( tmp );
            object = tmp;

        }
        else if( classname == "vec3" || classname == "vec4" )
        {
            // vec3 and vec4 have no handy .toList() method, so we have
            // to do it the 'hard way'...
            PyObject *tmp;
            classname == "vec3" ? tmp = PyTuple_New(3) : tmp = PyTuple_New(4);

            PyObject *x = PyObject_GetAttrString( object, "x" );
            Py_INCREF( x );
            PyObject *y = PyObject_GetAttrString( object, "y" );
            Py_INCREF( y );
            PyObject *z = PyObject_GetAttrString( object, "z" );
            Py_INCREF( z );
            PyTuple_SetItem( tmp, 0, x );
            PyTuple_SetItem( tmp, 1, y );
            PyTuple_SetItem( tmp, 2, z );
            if( classname == "vec4" )
            {
                PyObject *w = PyObject_GetAttrString( object, "w" );
                Py_INCREF( w );
                PyTuple_SetItem( tmp, 3, w );
            }
            object = tmp;
        }
        else if( classname == "quat" )
        {
            // quat has no handy .toList() method either...
            PyObject *tmp = PyTuple_New(4);

            PyObject *w = PyObject_GetAttrString( object, "w" );
            Py_INCREF( w );
            PyObject *x = PyObject_GetAttrString( object, "x" );
            Py_INCREF( x );
            PyObject *y = PyObject_GetAttrString( object, "y" );
            Py_INCREF( y );
            PyObject *z = PyObject_GetAttrString( object, "z" );
            Py_INCREF( z );
            PyTuple_SetItem( tmp, 0, w );
            PyTuple_SetItem( tmp, 1, x );
            PyTuple_SetItem( tmp, 2, y );
            PyTuple_SetItem( tmp, 3, z );
            object = tmp;
        }
        else
        {
            // Otherwise, barf on it
            PyErr_Format( gtoError(), "Can't handle '%s' class data directly."
                                      "  Convert it to a tuple or list first.",
                            classname.c_str() );
            return -1;
        }
    }

    // Put atoms directly into the buffer, and recurse on more complex types
    for( int i = 0; i < PySequence_Size( object ); ++i )
    {
        PyObject *item = PySequence_GetItem( object, i );
        if( PyTuple_Check( item )
           || PyList_Check( item )
           || PyInstance_Check( item ) )
        {
            flatten( item, data, maxItems, expectedTypeStr, converter, false );
        }
        else
        {
            // Add the atom to the buffer and move on
            data[pos] = converter( item );
            if( PyErr_Occurred() )
            {
                if( ! PyErr_ExceptionMatches( PyExc_TypeError ) )
                {
                    // This is something other than a type error, so
                    // this will cause a Python traceback later...
                    return -1;
                }
                // Data of a type not handled by the converter
                PyErr_Format( gtoError(), "Expected data of type '%s', but "
                                          "got '%s'", expectedTypeStr,
                                                      PyTypeName( item ) );
                return -1;
            }
            pos++;
            if( pos > maxItems )
            {
                return pos;
            }
        }
    }

    return pos;
}

// *****************************************************************************
// The next several functions implement the methods on the Python gto.Writer
// class.
// *****************************************************************************

// *****************************************************************************
// gto.Writer class constructor. Does nothing, but is required anyway
PyObject *gtoWriter_init( PyObject *_self, PyObject *args )
{
    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.open( filename )
PyObject *gtoWriter_open( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *filename;
    Gto::Writer::FileType filemode = Gto::Writer::CompressedGTO;

    if( ! PyArg_ParseTuple( args, "Os|i:gtoWriter_open", &self, &filename,
                                                         &filemode ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Create a new python writer object and add it to this instance's
    // dictionary
    gtoWriter_PyObject *writer = PyObject_NEW( gtoWriter_PyObject,
                                               &gtoWriter_PyObjectType );
    writer->m_writer = new Gto::Writer();
    writer->m_propCount = 0;
    writer->m_beginDataCalled = false;
    writer->m_objectDef = false;
    writer->m_componentDef = false;
    writer->m_propertyNames = new vector<string>;

    PyDict_SetItemString( self->in_dict, "__writerEngine", (PyObject *)writer );

    // Ask the writer to open the given file
    if( ! writer->m_writer->open( filename, filemode ) )
    {
        PyErr_Format( gtoError(), "Unable to open specified file: %s",
                      filename );
        return NULL;
    }

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.close()
PyObject *gtoWriter_close( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    if( ! PyArg_ParseTuple( args, "O:gtoWriter_close", &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Close the file
    writer->m_writer->close();

    // Remove the writer from the class dictionary
    PyDict_DelItemString( self->in_dict, "__writerEngine" );
    Py_DECREF( writer );

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.beginObject( name, protocol, protocolVersion )
PyObject *gtoWriter_beginObject( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    char *protocol;
    unsigned int protocolVersion;

    if( ! PyArg_ParseTuple( args, "Ossi:gtoWriter_beginObject",
                            &self, &name, &protocol, &protocolVersion ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == true )
    {
        PyErr_SetString( gtoError(), "Can't nest object declarations" );
        return NULL;
    }
    if( writer->m_beginDataCalled == true )
    {
        PyErr_SetString( gtoError(), "Once beginData is called, no new "
                                     "objects can be declared" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginObject( name, protocol, protocolVersion );
    writer->m_objectDef = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.endObject()
PyObject *gtoWriter_endObject( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endObject",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false )
    {
        PyErr_SetString( gtoError(), "endObject called before beginObject" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endObject();
    writer->m_objectDef = false;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.beginComponent( name, interp, flags )
PyObject *gtoWriter_beginComponent( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    char *interp = "";
    int flags = 0;

    // Try GTOv2 prototype first...
    if( ! PyArg_ParseTuple( args, "Os|i:gtoWriter_beginComponent",
                            &self, &name, &flags ) )
    {
        PyErr_Clear();
        // If that doesn't work, try the GTOv3 prototype
        if( ! PyArg_ParseTuple( args, "Oss|i:gtoWriter_beginComponent",
                                &self, &name, &interp, &flags ) )
        {
            // Invalid parameters, let Python do a stack trace
            return NULL;
        }
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false )
    {
        PyErr_SetString( gtoError(), "Components can only exist inside object "
                                     "blocks" );
        return NULL;
    }
    if( writer->m_componentDef == true )
    {
        PyErr_SetString( gtoError(), "Can't nest component declarations" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginComponent( name, interp, flags );
    writer->m_componentDef = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.endComponent()
PyObject *gtoWriter_endComponent( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endComponent",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_componentDef == false )
    {
        PyErr_SetString( gtoError(), "endComponent called before "
                                     "beginComponent" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endComponent();
    writer->m_componentDef = false;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// Implements gto.Writer.property( name, type, numElements, width, interp )
PyObject *gtoWriter_property( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *name;
    int type;
    int numElements;
    int width = 1;
    char *interp = "";

    if( ! PyArg_ParseTuple( args, "Osii|is:gtoWriter_property",
                            &self, &name, &type, &numElements,
                            &width, &interp ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_objectDef == false || writer->m_componentDef == false )
    {
        PyErr_SetString( gtoError(), "Properties can only exist inside "
                                     "object/component blocks" );
        return NULL;
    }

    // Store name for later dumbassness checking in propertyData()
    writer->m_propertyNames->push_back( name );

    // Make it so
    writer->m_writer->property( name,
                                (Gto::DataType)type,
                                numElements,
                                width,
                                interp );

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.intern( string | tuple | list )
PyObject *gtoWriter_intern( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    PyObject *data;

    if( ! PyArg_ParseTuple( args, "OO:gtoWriter_intern",
                            &self, &data ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Handle a single string
    if( PyString_Check( data ) )
    {
        char *str = PyString_AsString( data );
        writer->m_writer->intern( str );
    }
    // Handle a bunch of strings all at once
    else if( PySequence_Check( data ) )
    {
        for( int i = 0; i < PySequence_Size( data ); ++i )
        {
            PyObject *pstr = PySequence_GetItem( data, i );
            if( PyString_Check( pstr ) )
            {
                char *str = PyString_AsString( pstr );
                writer->m_writer->intern( str );
            }
            else if( PySequence_Check( pstr ) )
            {
                for( int j = 0; j < PySequence_Size( pstr ); ++j )
                {
                    PyObject *ppstr = PySequence_GetItem( pstr, j );
                    if( ! PyString_Check( ppstr ) )
                    {
                        PyErr_SetString( gtoError(),
                                         "Non-string in sub-sequence" );
                        return NULL;
                    }
                    char *str = PyString_AsString( ppstr );
                    writer->m_writer->intern( str );
                }
            }
            else
            {
                PyErr_SetString( gtoError(),
                                 "Non-string or sequence in sequence" );
                return NULL;
            }
        }
    }
    // We can't handle what we were given
    else
    {
        PyErr_SetString( gtoError(), "intern requires a string or a "
                                     "sequence of strings" );
        return NULL;
    }

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.lookup( string )
PyObject *gtoWriter_lookup( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    char *str;

    if( ! PyArg_ParseTuple( args, "Os:gtoWriter_lookup",
                            &self, &str ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_beginDataCalled == false )
    {
        PyErr_SetString( gtoError(), "lookup() cannot be used until "
                                     "beginData() is called" );
        return NULL;
    }

    // Make it so
    PyObject *strId_PyObj = PyInt_FromLong( writer->m_writer->lookup( str ) );

    Py_INCREF( strId_PyObj );
    return strId_PyObj;
}

// *****************************************************************************
// implements gto.Writer.beginData()
PyObject *gtoWriter_beginData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_beginData",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_writer->properties().size() == 0 )
    {
        PyErr_SetString( gtoError(), "There are no properties to write" );
        return NULL;
    }

    // Make it so
    writer->m_writer->beginData();
    writer->m_beginDataCalled = true;

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.endData()
PyObject *gtoWriter_endData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;

    if( ! PyArg_ParseTuple( args, "O:gtoWriter_endData",
                            &self ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( writer->m_beginDataCalled == false )
    {
        PyErr_SetString( gtoError(), "endData called before beginData" );
        return NULL;
    }

    // Make it so
    writer->m_writer->endData();

    Py_INCREF( Py_None );
    return Py_None;
}

// *****************************************************************************
// implements gto.Writer.propertyData( data )
PyObject *gtoWriter_propertyData( PyObject *_self, PyObject *args )
{
    PyInstanceObject *self;
    PyObject *rawdata;

    if( ! PyArg_ParseTuple( args, "OO:gtoWriter_propertyData",
                            &self, &rawdata ) )
    {
        // Invalid parameters, let Python do a stack trace
        return NULL;
    }

    // Get a handle to our Gto::Writer instance
    gtoWriter_PyObject *writer =
            (gtoWriter_PyObject *)PyDict_GetItemString( self->in_dict,
                                                        "__writerEngine" );
    if( writer == NULL )
    {
        PyErr_SetString( gtoError(), "no file is open." );
        return NULL;
    }
    assert( writer->m_writer != NULL );

    // Check for dumbassness
    if( ! writer->m_beginDataCalled )
    {
        PyErr_SetString( gtoError(), "propertyData called before beginData" );
        return NULL;
    }

    // If we're handed a single value, tuple-ize it for the code below
    if( PyInt_Check( rawdata )
        || PyFloat_Check( rawdata )
        || PyString_Check( rawdata ) )
    {
        PyObject *tmp = PyTuple_New( 1 );
        PyTuple_SetItem( tmp, 0, rawdata );
        Py_DECREF( rawdata );
        rawdata = tmp;
    }

    // Get a handle to the property definition for the current property
    // and do some sanity checking
    Gto::PropertyHeader prop;
    prop = writer->m_writer->properties()[writer->m_propCount];
    if( writer->m_propCount >= writer->m_writer->properties().size() )
    {
        PyErr_SetString( gtoError(), "Undeclared data." );
        return NULL;
    }

    const char *currentPropName = (*writer->m_propertyNames)[writer->m_propCount].c_str();

    // Determine how many elements we have in the data
    int dataSize = prop.size * elementSize(prop.dims);

    // Write that data!
    if( prop.type == Gto::Int )
    {
        int *data = new int[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "int", PyInt_AsInt );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }

    if( prop.type == Gto::Float )
    {
        float *data = new float[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "float",
                                PyFloat_AsFloat );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Double )
    {
        double *data = new double[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "double",
                                PyFloat_AsDouble );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Short )
    {
        unsigned short *data = new unsigned short[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "short",
                                PyInt_AsShort );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::Byte )
    {
        unsigned char *data = new unsigned char[dataSize];
        int numItems = flatten( rawdata, data, dataSize, "byte",
                                PyInt_AsByte );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }
    if( prop.type == Gto::String )
    {
        char **strings = new char *[dataSize];
        int numItems = flatten( rawdata, strings, dataSize, "string",
                                PyString_AsString );
        if( PyErr_Occurred() )
        {
            return NULL;
        }
        if( numItems != dataSize )
        {
            PyErr_Format( gtoError(), "Property '%s' was declared as having %d"
                          " x %d values, but %d values were given for writing",
                          currentPropName, prop.size, int(elementSize(prop.dims)),
                          numItems );
            return NULL;
        }

        int *data = new int[dataSize];
        for( int i = 0; i < numItems; ++i )
        {
            data[i] = writer->m_writer->lookup( strings[i] );
            if( data[i] == -1 )
            {
                PyErr_Format( gtoError(),
                       "'%s' needs to be \"interned\" before it can "
                       "be used as data in property #%d",
                       strings[i], writer->m_propCount );
                return NULL;
            }
        }
        writer->m_writer->propertyData( data );
        writer->m_propCount++;

        delete [] strings;
        delete [] data;

        Py_INCREF( Py_None );
        return Py_None;
    }

    PyErr_Format( gtoError(), "Undefined property type: %d  in property '%s'",
                     prop.type, currentPropName );
    return NULL;
}

}; // End namespace PyGto


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>Hebrew Strong Dictionary</title>

Hebrew Strong Dictionary

			Hebrew:
			<input type="text" id="heb">
			<button onclick="query_hebrew()">Query</button>

			Strong Number:
			<input type="text" id="strong_number">
			<button onclick="query_strong()">Query</button>

		Copyright 2017 Sinri Edogawa. Dictionary data powered by Project HebrewLexicon.


using System;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using Microsoft.Build.BuildEngine;
using ExcessCompiler;
using System.Xml.Linq;

namespace Excess.CompilerTasks
{
	/////////////////////////////////////////////////////////////////////////////
	// My MSBuild Task
	public class ExcessCompilerTask : Task
	{
		#region Constructors
		/// <summary>
		/// Constructor. This is the constructor that will be used
		/// when the task run.
		/// </summary>
		public ExcessCompilerTask()
		{
		}
		#endregion

		#region Public Properties and related Fields
		private string[] sourceFiles;
		/// <summary>
		/// List of Python source files that should be compiled into the assembly
		/// </summary>
		[Required()]
		public string[] SourceFiles
		{
			get { return sourceFiles; }
			set { sourceFiles = value; }
		}

		private string outputAssembly;
		/// <summary>
		/// Output Assembly (including extension)
		/// </summary>
		[Required()]
		public string OutputAssembly
		{
			get { return outputAssembly; }
			set { outputAssembly = value; }
		}

		private ITaskItem[] referencedAssemblies = new ITaskItem[0];
		/// <summary>
		/// List of dependent assemblies
		/// </summary>
		public ITaskItem[] ReferencedAssemblies
		{
			get { return referencedAssemblies; }
			set
			{
				if (value != null)
				{
					referencedAssemblies = value;
				}
				else
				{
					referencedAssemblies = new ITaskItem[0];
				}

			}
		}

		private ITaskItem[] resourceFiles = new ITaskItem[0];
		/// <summary>
		/// List of resource files
		/// </summary>
		public ITaskItem[] ResourceFiles
		{
			get { return resourceFiles; }
			set
			{
				if (value != null)
				{
					resourceFiles = value;
				}
				else
				{
					resourceFiles = new ITaskItem[0];
				}

			}
		}

		private string mainFile;
		/// <summary>
		/// For applications, which file is the entry point
		/// </summary>
		[Required()]
		public string MainFile
		{
			get { return mainFile; }
			set { mainFile = value; }
		}

		private string targetKind;
		/// <summary>
		/// Target type (exe, winexe, library)
		/// These will be mapped to System.Reflection.Emit.PEFileKinds
		/// </summary>
		public string TargetKind
		{
			get { return targetKind; }
			set { targetKind = value.ToLower(CultureInfo.InvariantCulture); }
		}
		private bool debugSymbols = true;
		/// <summary>
		/// Generate debug information
		/// </summary>
		public bool DebugSymbols
		{
			get { return debugSymbols; }
			set { debugSymbols = value; }
		}
		private string projectPath = null;
		/// <summary>
		/// This should be set to $(MSBuildProjectDirectory)
		/// </summary>
		public string ProjectPath
		{
			get { return projectPath; }
			set { projectPath = value; }
		}

		private bool useExperimentalCompiler;
		/// <summary>
		/// This property is only needed because Iron Python does not officially support building real .Net assemblies.
		/// For WAP scenarios, we need to support real assemblies and as such we use an alternate approach to build those assemblies.
		/// </summary>
		public bool UseExperimentalCompiler
		{
			get { return useExperimentalCompiler; }
			set { useExperimentalCompiler = value; }
		}

		#endregion

		/// <summary>
		/// Main entry point for the task
		/// </summary>
		/// <returns></returns>
		public override bool Execute()
		{
            string filePath = Path.Combine(projectPath, MainFile);
            XAttribute version = XElement.Load(filePath).Attribute("version");
            bool old_version = version != null && version.Value == "0.9.4";
            if (old_version)
            {
                //call xss.exe
                return true;
            }

            ExcessModelService service = ExcessModelService.getInstance();
            List<ExcessErrorInfo> errors = new List<ExcessErrorInfo>();
            bool success = service.Model.buildProject(filePath, errors);
            if (errors.Count == 0)
            {
                Engine engine = new Engine();
                engine.DefaultToolsVersion = "4.0";

                // Instantiate a new FileLogger to generate build log
                myLogger logger = new myLogger(Log);

                // Set the logfile parameter to indicate the log destination
                logger.Parameters = @"logfile=C:\dev\XKP_BIN\build.log";

                // Register the logger with the engine
                engine.RegisterLogger(logger);

                // Build a project file
                string appName = service.Model.getAppName(filePath);
                string slnPath = Path.Combine(projectPath, @"bin\debug\" + appName + ".sln");
                try
                {
                    success = engine.BuildProjectFile(slnPath);
                }
                catch (Exception e)
                {
                    success = false;
                }

                //Unregister all loggers to close the log file
                engine.UnregisterAllLoggers();

                if (success)
                    Console.WriteLine("Build succeeded.");
                else
                    Console.WriteLine(@"Build failed. View C:\temp\build.log for details");

                return true;
            }

            //foreach (ExcessErrorInfo error in errors)
            //{
            //    Log.LogError("", "", "", error.File, error.BeginLine, error.BeginColumn, error.BeginLine, error.BeginColumn + 1, error.desc);
            //}

            return success;
		}

		/// <summary>
		/// Initialize compiler options based on task parameters
		/// </summary>
		/// <returns>false if failed</returns>
		private bool InitializeCompiler()
		{
			return true;
		}
	}

    internal class myLogger : Logger
    {
        public myLogger(TaskLoggingHelper log)
        {
            log_ = log;
        }

        public override void Initialize(Microsoft.Build.Framework.IEventSource eventSource)
        {
            ////Register for the ProjectStarted, TargetStarted, and ProjectFinished events
            //eventSource. ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
            //eventSource.TargetStarted += new TargetStartedEventHandler(eventSource_TargetStarted);
            eventSource.ErrorRaised += new BuildErrorEventHandler(ErrorHandler);
        }

        private void ErrorHandler(object sender, BuildErrorEventArgs e)
        {
            //td: !! send the errors back to xs
            log_.LogError(e.Subcategory, e.Code, e.HelpKeyword, e.File, e.LineNumber, e.ColumnNumber, e.EndLineNumber, e.EndColumnNumber, e.Message);
        }

        private TaskLoggingHelper log_;
    }
}

using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using Microsoft.Build.BuildEngine;
using ExcessCompiler;
using System.Xml.Linq;
using Newtonsoft.Json;

namespace Excess.CompilerTasks
{
	/////////////////////////////////////////////////////////////////////////////
	// My MSBuild Task
    public class Log
    {
        public string text { get; set; }
        public string type { get; set; }
    }
	public class ExcessCompilerTask : Task
	{
		#region Constructors
		/// <summary>
		/// Constructor. This is the constructor that will be used
		/// when the task run.
		/// </summary>
		public ExcessCompilerTask()
		{
		}
		#endregion

		#region Public Properties and related Fields
		private string[] sourceFiles;
		/// <summary>
		/// List of Python source files that should be compiled into the assembly
		/// </summary>
		[Required()]
		public string[] SourceFiles
		{
			get { return sourceFiles; }
			set { sourceFiles = value; }
		}

		private string outputAssembly;
		/// <summary>
		/// Output Assembly (including extension)
		/// </summary>
		[Required()]
		public string OutputAssembly
		{
			get { return outputAssembly; }
			set { outputAssembly = value; }
		}

		private ITaskItem[] referencedAssemblies = new ITaskItem[0];
		/// <summary>
		/// List of dependent assemblies
		/// </summary>
		public ITaskItem[] ReferencedAssemblies
		{
			get { return referencedAssemblies; }
			set
			{
				if (value != null)
				{
					referencedAssemblies = value;
				}
				else
				{
					referencedAssemblies = new ITaskItem[0];
				}

			}
		}

		private ITaskItem[] resourceFiles = new ITaskItem[0];
		/// <summary>
		/// List of resource files
		/// </summary>
		public ITaskItem[] ResourceFiles
		{
			get { return resourceFiles; }
			set
			{
				if (value != null)
				{
					resourceFiles = value;
				}
				else
				{
					resourceFiles = new ITaskItem[0];
				}

			}
		}

		private string mainFile;
		/// <summary>
		/// For applications, which file is the entry point
		/// </summary>
		[Required()]
		public string MainFile
		{
			get { return mainFile; }
			set { mainFile = value; }
		}

		private string targetKind;
		/// <summary>
		/// Target type (exe, winexe, library)
		/// These will be mapped to System.Reflection.Emit.PEFileKinds
		/// </summary>
		public string TargetKind
		{
			get { return targetKind; }
			set { targetKind = value.ToLower(CultureInfo.InvariantCulture); }
		}
		private bool debugSymbols = true;
		/// <summary>
		/// Generate debug information
		/// </summary>
		public bool DebugSymbols
		{
			get { return debugSymbols; }
			set { debugSymbols = value; }
		}
		private string projectPath = null;
		/// <summary>
		/// This should be set to $(MSBuildProjectDirectory)
		/// </summary>
		public string ProjectPath
		{
			get { return projectPath; }
			set { projectPath = value; }
		}

		private bool useExperimentalCompiler;
		/// <summary>
		/// This property is only needed because Iron Python does not officially support building real .Net assemblies.
		/// For WAP scenarios, we need to support real assemblies and as such we use an alternate approach to build those assemblies.
		/// </summary>
		public bool UseExperimentalCompiler
		{
			get { return useExperimentalCompiler; }
			set { useExperimentalCompiler = value; }
		}

		#endregion

		/// <summary>
		/// Main entry point for the task
		/// </summary>
		/// <returns></returns>
		public override bool Execute()
		{
            string filePath = Path.Combine(projectPath, MainFile);
            XAttribute version = XElement.Load(filePath).Attribute("version");
            bool old_version = version != null && version.Value == "0.9.4";
            if (old_version)
            {
                //call xss.exe
                Process proc = new Process();
                proc.StartInfo = new ProcessStartInfo("xss.exe");
                proc.StartInfo.Arguments = filePath + " json";
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.UseShellExecute = false;

                bool success_ = proc.Start();

                string output_string = proc.StandardOutput.ReadToEnd();

                List<Log> logs = JsonConvert.DeserializeObject<List<Log>>(output_string);

                foreach (Log l in logs)
                {
                    if (l.type == "error")
                    {
                        Log.LogError(l.text);
                        success_ = false;
                    }
                    if (l.type == "msg")
                        Log.LogMessage(l.text);
                    if (l.type == "log")
                        Log.LogMessage(l.text);
                }

                return success_;
            }

            ExcessModelService service = ExcessModelService.getInstance();
            List<ExcessErrorInfo> errors = new List<ExcessErrorInfo>();
            bool success = service.Model.buildProject(filePath, errors);
            if (errors.Count == 0)
            {
                Engine engine = new Engine();
                engine.DefaultToolsVersion = "4.0";

                // Instantiate a new FileLogger to generate build log
                myLogger logger = new myLogger(Log);

                // Set the logfile parameter to indicate the log destination
                logger.Parameters = @"logfile=C:\dev\XKP_BIN\build.log";

                // Register the logger with the engine
                engine.RegisterLogger(logger);

                // Build a project file
                string appName = service.Model.getAppName(filePath);
                string slnPath = Path.Combine(projectPath, @"bin\debug\" + appName + ".sln");
                try
                {
                    success = engine.BuildProjectFile(slnPath);
                }
                catch (Exception e)
                {
                    success = false;
                }

                //Unregister all loggers to close the log file
                engine.UnregisterAllLoggers();

                if (success)
                    Console.WriteLine("Build succeeded.");
                else
                    Console.WriteLine(@"Build failed. View C:\temp\build.log for details");

                return true;
            }

            //foreach (ExcessErrorInfo error in errors)
            //{
            //    Log.LogError("", "", "", error.File, error.BeginLine, error.BeginColumn, error.BeginLine, error.BeginColumn + 1, error.desc);
            //}

            return success;
		}

		/// <summary>
		/// Initialize compiler options based on task parameters
		/// </summary>
		/// <returns>false if failed</returns>
		private bool InitializeCompiler()
		{
			return true;
		}
	}

    internal class myLogger : Logger
    {
        public myLogger(TaskLoggingHelper log)
        {
            log_ = log;
        }

        public override void Initialize(Microsoft.Build.Framework.IEventSource eventSource)
        {
            ////Register for the ProjectStarted, TargetStarted, and ProjectFinished events
            //eventSource. ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
            //eventSource.TargetStarted += new TargetStartedEventHandler(eventSource_TargetStarted);
            eventSource.ErrorRaised += new BuildErrorEventHandler(ErrorHandler);
        }

        private void ErrorHandler(object sender, BuildErrorEventArgs e)
        {
            //td: !! send the errors back to xs
            log_.LogError(e.Subcategory, e.Code, e.HelpKeyword, e.File, e.LineNumber, e.ColumnNumber, e.EndLineNumber, e.EndColumnNumber, e.Message);
        }

        private TaskLoggingHelper log_;
    }
}


module Devise
  module Twitter
    VERSION = "0.1.2.pre"
  end
end

module Devise
  module Twitter
    VERSION = "0.1.2"
  end
end


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
        signal(SIGCHLD, SIG_IGN);
	extern char **environ;
	printf("Starting artha...\n");
	pid_t artha_fork;
	if( (artha_fork=fork()) < 0 ) {
		fprintf(stderr,"Failed to fork\n");
		exit(1);
	}
	if(artha_fork>0) {
		printf("Successfull fork...\n");
		exit(0);
	}
	char *cmd_line[]={"/usr/bin/artha",NULL};
	execve("/usr/bin/artha",cmd_line,environ);
	fprintf(stderr,"Failed to execute\n");
	return 1;
}

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
    signal(SIGCHLD, SIG_IGN); // Reparent to init
	extern char **environ;
	printf("Starting artha...\n");
	pid_t artha_fork;
	if( (artha_fork=fork()) < 0 ) {
		fprintf(stderr,"Failed to fork\n");
		exit(1);
	}
	if(artha_fork>0) {
		printf("Successfull fork...\n");
		exit(0);
	}
	char *cmd_line[]={"/usr/bin/artha",NULL};
	execve("/usr/bin/artha",cmd_line,environ);
	fprintf(stderr,"Failed to execute\n");
	return 1;
}


<?php

/**
 * A MySQL store.
 *
 * @package OpenID
 */

/**
 * Require the base class file.
 */
require_once "Auth/OpenID/SQLStore.php";

/**
 * An SQL store that uses MySQL as its backend.
 *
 * @package OpenID
 */
class Auth_OpenID_MySQLStore extends Auth_OpenID_SQLStore {
    /**
     * @access private
     */
    function setSQL()
    {
        $this->sql['nonce_table'] =
            "CREATE TABLE %s (\n".
            "  server_url VARCHAR(2047) NOT NULL,\n".
            "  timestamp INTEGER NOT NULL,\n".
            "  salt CHAR(40) NOT NULL,\n".
            "  UNIQUE (server_url(255), timestamp, salt)\n".
            ") ENGINE=InnoDB";

        $this->sql['assoc_table'] =
            "CREATE TABLE %s (\n".
            "  server_url BLOB NOT NULL,\n".
            "  handle VARCHAR(255) NOT NULL,\n".
            "  secret BLOB NOT NULL,\n".
            "  issued INTEGER NOT NULL,\n".
            "  lifetime INTEGER NOT NULL,\n".
            "  assoc_type VARCHAR(64) NOT NULL,\n".
            "  PRIMARY KEY (server_url(255), handle)\n".
            ") ENGINE=InnoDB";

        $this->sql['set_assoc'] =
            "REPLACE INTO %s (server_url, handle, secret, issued,\n".
            "  lifetime, assoc_type) VALUES (?, ?, !, ?, ?, ?)";

        $this->sql['get_assocs'] =
            "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
            "WHERE server_url = ?";

        $this->sql['get_assoc'] =
            "SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
            "WHERE server_url = ? AND handle = ?";

        $this->sql['remove_assoc'] =
            "DELETE FROM %s WHERE server_url = ? AND handle = ?";

        $this->sql['add_nonce'] =
            "INSERT INTO %s (server_url, timestamp, salt) VALUES (?, ?, ?)";

        $this->sql['clean_nonce'] =
            "DELETE FROM %s WHERE timestamp < ?";

        $this->sql['clean_assoc'] =
            "DELETE FROM %s WHERE issued + lifetime < ?";
    }

    /**
     * @access private
     */
    function blobEncode($blob)
    {
        return "0x" . bin2hex($blob);
    }
}

?>