text:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v@@BUILD_VERSION@@
// 	See http://java.sun.com/xml/jaxb
// 	Any modifications to this file will be lost upon recompilation of the source schema.
// 	Generated on: 2011.03.27 um 12:23:14 MESZ
//

package biz.wolschon.fileformats.gnucash.jwsdpimpl.generated;

/**
 * Java content class for anonymous complex type.
 *
The following schema fragment specifies the expected 	content contained within this java content object. 	(defined at file:/C:/Users/fox/Documents/My%20Dropbox/Sourcecode/jGnucashLib-GPL/plugins/biz.wolschon.finance.jgnucash.viewer.main/source/gnucash.xsd line 416)
 *

 *

 * <complexType>
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="cust_guid">
 *           <complexType>
 *             <simpleContent>
 *               <extension base="<http://www.w3.org/2001/XMLSchema>string">
 *                 <attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *               </extension>
 *             </simpleContent>
 *           </complexType>
 *         </element>
 *         <element name="cust_name">
 *           <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *             <minLength value="1"/>
 *           </restriction>
 *         </element>
 *         <element name="cust_id" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="cust_addr" type="{}address"/>
 *         <element name="cust_shipaddr" type="{}address"/>
 *         <element name="cust_notes" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="cust_terms" minOccurs="0">
 *           <complexType>
 *             <simpleContent>
 *               <extension base="<http://www.w3.org/2001/XMLSchema>string">
 *                 <attribute name="type" use="required">
 *                   <simpleType>
 *                     <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
 *                       <enumeration value="guid"/>
 *                     </restriction>
 *                   </simpleType>
 *                 </attribute>
 *               </extension>
 *             </simpleContent>
 *           </complexType>
 *         </element>
 *         <element name="cust_taxincluded" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="cust_active" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         <element name="cust_discount" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="cust_credit" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="cust_currency">
 *           <complexType>
 *             <complexContent>
 *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *                 <sequence>
 *                   <element ref="{}cmdty_space"/>
 *                   <element ref="{}cmdty_id"/>
 *                 </sequence>
 *               </restriction>
 *             </complexContent>
 *           </complexType>
 *         </element>
 *         <element name="cust_use-tt" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         <element name="cust_taxtable" minOccurs="0">
 *           <complexType>
 *             <simpleContent>
 *               <extension base="<http://www.w3.org/2001/XMLSchema>string">
 *                 <attribute name="type" use="required">
 *                   <simpleType>
 *                     <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
 *                       <enumeration value="guid"/>
 *                     </restriction>
 *                   </simpleType>
 *                 </attribute>
 *               </extension>
 *             </simpleContent>
 *           </complexType>
 *         </element>
 *         <element name="cust_slots" type="{}slots_type" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 *
 */
public interface GncGncCustomerType {

    /**
     * Gets the value of the custShipaddr property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address getCustShipaddr();

    /**
     * Sets the value of the custShipaddr property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address}
     */
    void setCustShipaddr(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address value);

    /**
     * Gets the value of the custTaxincluded property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustTaxincluded();

    /**
     * Sets the value of the custTaxincluded property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustTaxincluded(java.lang.String value);

    /**
     * Gets the value of the custTerms property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTermsType}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTermsType getCustTerms();

    /**
     * Sets the value of the custTerms property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTermsType}
     */
    void setCustTerms(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTermsType value);

    /**
     * Gets the value of the custActive property.
     *
     */
    int getCustActive();

    /**
     * Sets the value of the custActive property.
     *
     */
    void setCustActive(int value);

    /**
     * Gets the value of the custCurrency property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustCurrencyType}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustCurrencyType getCustCurrency();

    /**
     * Sets the value of the custCurrency property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustCurrencyType}
     */
    void setCustCurrency(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustCurrencyType value);

    /**
     * Gets the value of the custTaxtable property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTaxtableType}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTaxtableType getCustTaxtable();

    /**
     * Sets the value of the custTaxtable property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTaxtableType}
     */
    void setCustTaxtable(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustTaxtableType value);

    /**
     * Gets the value of the custUseTt property.
     *
     */
    int getCustUseTt();

    /**
     * Sets the value of the custUseTt property.
     *
     */
    void setCustUseTt(int value);

    /**
     * Gets the value of the custDiscount property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustDiscount();

    /**
     * Sets the value of the custDiscount property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustDiscount(java.lang.String value);

    /**
     * Gets the value of the custCredit property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustCredit();

    /**
     * Sets the value of the custCredit property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustCredit(java.lang.String value);

    /**
     * Gets the value of the custAddr property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address getCustAddr();

    /**
     * Sets the value of the custAddr property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address}
     */
    void setCustAddr(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.Address value);

    /**
     * Gets the value of the custSlots property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.SlotsType}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.SlotsType getCustSlots();

    /**
     * Sets the value of the custSlots property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.SlotsType}
     */
    void setCustSlots(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.SlotsType value);

    /**
     * Gets the value of the custId property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustId();

    /**
     * Sets the value of the custId property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustId(java.lang.String value);

    /**
     * Gets the value of the custName property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustName();

    /**
     * Sets the value of the custName property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustName(java.lang.String value);

    /**
     * Gets the value of the custGuid property.
     *
     * @return
     *     possible object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustGuidType}
     */
    biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustGuidType getCustGuid();

    /**
     * Sets the value of the custGuid property.
     *
     * @param value
     *     allowed object is
     *     {@link biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustGuidType}
     */
    void setCustGuid(biz.wolschon.fileformats.gnucash.jwsdpimpl.generated.GncGncCustomerType.CustGuidType value);

    /**
     * Gets the value of the version property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getVersion();

    /**
     * Sets the value of the version property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setVersion(java.lang.String value);

    /**
     * Gets the value of the custNotes property.
     *
     * @return
     *     possible object is
     *     {@link java.lang.String}
     */
    java.lang.String getCustNotes();

    /**
     * Sets the value of the custNotes property.
     *
     * @param value
     *     allowed object is
     *     {@link java.lang.String}
     */
    void setCustNotes(java.lang.String value);

    /**
     * Java content class for anonymous complex type.
     *
The following schema fragment specifies the expected 	content contained within this java content object. 	(defined at file:/C:/Users/fox/Documents/My%20Dropbox/Sourcecode/jGnucashLib-GPL/plugins/biz.wolschon.finance.jgnucash.viewer.main/source/gnucash.xsd line 458)
     *

     *

     * <complexType>
     *   <complexContent>
     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
     *       <sequence>
     *         <element ref="{}cmdty_space"/>
     *         <element ref="{}cmdty_id"/>
     *       </sequence>
     *     </restriction>
     *   </complexContent>
     * </complexType>
     *

     *
     */
    public interface CustCurrencyType {

        /**
         * Gets the value of the cmdtyId property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getCmdtyId();

        /**
         * Sets the value of the cmdtyId property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setCmdtyId(java.lang.String value);

        /**
         * Gets the value of the cmdtySpace property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getCmdtySpace();

        /**
         * Sets the value of the cmdtySpace property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setCmdtySpace(java.lang.String value);

    }

    /**
     * Java content class for anonymous complex type.
     *
The following schema fragment specifies the expected 	content contained within this java content object. 	(defined at file:/C:/Users/fox/Documents/My%20Dropbox/Sourcecode/jGnucashLib-GPL/plugins/biz.wolschon.finance.jgnucash.viewer.main/source/gnucash.xsd line 419)
     *

     *

     * <complexType>
     *   <simpleContent>
     *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
     *       <attribute name="type" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
     *     </extension>
     *   </simpleContent>
     * </complexType>
     *

     *
     */
    public interface CustGuidType {

        /**
         * Gets the value of the value property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getValue();

        /**
         * Sets the value of the value property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setValue(java.lang.String value);

        /**
         * Gets the value of the type property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getType();

        /**
         * Sets the value of the type property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setType(java.lang.String value);

    }

    /**
     * Java content class for anonymous complex type.
     *
The following schema fragment specifies the expected 	content contained within this java content object. 	(defined at file:/C:/Users/fox/Documents/My%20Dropbox/Sourcecode/jGnucashLib-GPL/plugins/biz.wolschon.finance.jgnucash.viewer.main/source/gnucash.xsd line 467)
     *

     *

     * <complexType>
     *   <simpleContent>
     *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
     *       <attribute name="type" use="required">
     *         <simpleType>
     *           <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
     *             <enumeration value="guid"/>
     *           </restriction>
     *         </simpleType>
     *       </attribute>
     *     </extension>
     *   </simpleContent>
     * </complexType>
     *

     *
     */
    public interface CustTaxtableType {

        /**
         * Gets the value of the value property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getValue();

        /**
         * Sets the value of the value property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setValue(java.lang.String value);

        /**
         * Gets the value of the type property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getType();

        /**
         * Sets the value of the type property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setType(java.lang.String value);

    }

    /**
     * Java content class for anonymous complex type.
     *
The following schema fragment specifies the expected 	content contained within this java content object. 	(defined at file:/C:/Users/fox/Documents/My%20Dropbox/Sourcecode/jGnucashLib-GPL/plugins/biz.wolschon.finance.jgnucash.viewer.main/source/gnucash.xsd line 439)
     *

     *

     * <complexType>
     *   <simpleContent>
     *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
     *       <attribute name="type" use="required">
     *         <simpleType>
     *           <restriction base="{http://www.w3.org/2001/XMLSchema}NMTOKEN">
     *             <enumeration value="guid"/>
     *           </restriction>
     *         </simpleType>
     *       </attribute>
     *     </extension>
     *   </simpleContent>
     * </complexType>
     *

     *
     */
    public interface CustTermsType {

        /**
         * Gets the value of the value property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getValue();

        /**
         * Sets the value of the value property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setValue(java.lang.String value);

        /**
         * Gets the value of the type property.
         *
         * @return
         *     possible object is
         *     {@link java.lang.String}
         */
        java.lang.String getType();

        /**
         * Sets the value of the type property.
         *
         * @param value
         *     allowed object is
         *     {@link java.lang.String}
         */
        void setType(java.lang.String value);

    }

}


text:
/*	$FreeBSD: releng/9.3/sys/netipsec/xform_tcp.c 196019 2009-08-01 19:26:27Z rwatson $ */

/*-
 * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
 */

/* TCP MD5 Signature Option (RFC2385) */
#include "opt_inet.h"
#include "opt_inet6.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/protosw.h>
#include <sys/sysctl.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_var.h>

#include <net/route.h>
#include <net/vnet.h>

#include <netipsec/ipsec.h>
#include <netipsec/xform.h>

#ifdef INET6
#include <netinet/ip6.h>
#include <netipsec/ipsec6.h>
#endif

#include <netipsec/key.h>
#include <netipsec/key_debug.h>

/*
 * Initialize a TCP-MD5 SA. Called when the SA is being set up.
 *
 * We don't need to set up the tdb prefixed fields, as we don't use the
 * opencrypto code; we just perform a key length check.
 *
 * XXX: Currently we only allow a single 'magic' SPI to be used.
 *
 * This allows per-host granularity without affecting the userland
 * interface, which is a simple socket option toggle switch,
 * TCP_SIGNATURE_ENABLE.
 *
 * To allow per-service granularity requires that we have a means
 * of mapping port to SPI. The mandated way of doing this is to
 * use SPD entries to specify packet flows which get the TCP-MD5
 * treatment, however the code to do this is currently unstable
 * and unsuitable for production use.
 *
 * Therefore we use this compromise in the meantime.
 */
static int
tcpsignature_init(struct secasvar *sav, struct xformsw *xsp)
{
	int keylen;

	if (sav->spi != htonl(TCP_SIG_SPI)) {
		DPRINTF(("%s: SPI must be TCP_SIG_SPI (0x1000)\n",
		    __func__));
		return (EINVAL);
	}
	if (sav->alg_auth != SADB_X_AALG_TCP_MD5) {
		DPRINTF(("%s: unsupported authentication algorithm %u\n",
		    __func__, sav->alg_auth));
		return (EINVAL);
	}
	if (sav->key_auth == NULL) {
		DPRINTF(("%s: no authentication key present\n", __func__));
		return (EINVAL);
	}
	keylen = _KEYLEN(sav->key_auth);
	if ((keylen < TCP_KEYLEN_MIN) || (keylen > TCP_KEYLEN_MAX)) {
		DPRINTF(("%s: invalid key length %u\n", __func__, keylen));
		return (EINVAL);
	}

	return (0);
}

/*
 * Paranoia.
 *
 * Called when the SA is deleted.
 */
static int
tcpsignature_zeroize(struct secasvar *sav)
{

	if (sav->key_auth)
		bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth));

	sav->tdb_cryptoid = 0;
	sav->tdb_authalgxform = NULL;
	sav->tdb_xform = NULL;

	return (0);
}

/*
 * Verify that an input packet passes authentication.
 * Called from the ipsec layer.
 * We do this from within tcp itself, so this routine is just a stub.
 */
static int
tcpsignature_input(struct mbuf *m, struct secasvar *sav, int skip,
    int protoff)
{

	return (0);
}

/*
 * Prepend the authentication header.
 * Called from the ipsec layer.
 * We do this from within tcp itself, so this routine is just a stub.
 */
static int
tcpsignature_output(struct mbuf *m, struct ipsecrequest *isr,
    struct mbuf **mp, int skip, int protoff)
{

	return (EINVAL);
}

static struct xformsw tcpsignature_xformsw = {
	XF_TCPSIGNATURE,	XFT_AUTH,		"TCPMD5",
	tcpsignature_init,	tcpsignature_zeroize,
	tcpsignature_input,	tcpsignature_output
};

static void
tcpsignature_attach(void)
{

	xform_register(&tcpsignature_xformsw);
}

SYSINIT(tcpsignature_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST,
    tcpsignature_attach, NULL);

redpajama_set_name: RedPajamaGithub


text:
require 'timeout'  # for TimeoutError

# = Timer
#
# Provides a strightforward means for controlling time critical execution.
# Can be used as a "stop watch" timer or as a "time bomb" timer.
#
#   t = Timer.new(10) { raise TimeoutError, "timeout!" }
#   t.start
#     :      # done within 10sec timeout
#   t.stop
#   t.start
#     :
#   if condition then
#     t.reset       #--> restart timer
#   end
#
# A Kernel method is also provided for easily timing the exectuion of a block.
#
#   timed { |timer|
#      timer.total_time.round #=> 0
#
#      sleep 1
#      timer.total_time.round #=> 1
#
#      timer.stop
#      timer.total_time.round #=> 1
#
#      sleep 2
#      timer.total_time.round #=> 1
#
#      timer.start
#      timer.total_time.round #=> 1
#
#      sleep 1
#      timer.total_time.round #=> 2
#   }

class Timer

  attr_reader :start_time, :end_time
  attr_accessor :time_limit

  def initialize( time_limit=nil, &block )
    # standard timer
    @start_time = nil
    @end_time = nil
    @total_time = 0
    @runnning = nil
    # for using time limit
    @time_limit = time_limit
    @on_timeout = block
    @current_thread = nil
    @timer_thread = nil
  end

  def on_timeout( &block )
    if block then
      @on_timeout = block
      true
    else
      false
    end
  end

  # Start the timer.

  def start
    @running = true
    @start_time = Time.now

    limit if @time_limit

    self

    #if block_given? then
    #  begin
    #    yield( self )
    #  ensure
    #    stop
    #  end
    #else
    #  @time_limit
    #end
  end

  # Establish a time limit on execution.

  def limit( time_limit=nil )
    if @time_limit || time_limit
      @current_thread = Thread.current
      @timer_thread = Thread.fork {
        sleep @time_limit
        if @on_timeout then
          @on_timeout.call @time_limit
        else
          @current_thread.raise TimeoutError, "#{@time_limit} seconds past"
        end
      }
    end
  end

  # Kill time limit thread, if any.

  def defuse
    if @timer_thread
      Thread.kill @timer_thread
      @timer_thread = nil
    end
  end

  # Stops timer and returns total time.
  # If timer was not running returns false.

  def stop
    if @running
      defuse
      # record running time
      @end_time = Time.now
      @running = false
      @total_time += (@end_time - @start_time)
    else
      nil
    end
  end

  # Stops and resets the timer. If the timer was running
  # returns the total time. If not returns 0.

  def reset
    if running?
      r = stop
    else
      r = 0
    end
    @total_time = 0
    return r
  end

  # Resets the time limit. Same as:
  #
  #   t.stop
  #   t.start
  #

  def reset_limit
    #stop
    #start
    defuse
    limit
  end

  # Queries whether the timer is still running.

  def running?
    return @running
  end

  # Queries whether the timer is still not running.

  def stopped?
    return !@running
  end

  # Queries total recorded time of timer.

  def total_time
    if running? then
      return @total_time + (Time.now - @start_time)
    else
      return @total_time
    end
  end

  #
  # Timer::Dummy - Dummy Timer (i.e. no real time limit)
  #--
  # NEEDS WORK!
  #++

  class Dummy < self
    def start
      if block_given? then
        yield
      else
        time_limit()
      end
    end

    def stop
      false
    end
  end #class Dummy

end #class Timer

module Kernel

  # Takes a block and returns the total time it took to execute.

  def timed
    yield( timer = Timer.new.start )
    return timer.total_time
  end

end