text:
formbuilder
==================

This project has many changes to it, but it is heavily based on the jquery.formbuilder project. (https://github.com/botskonet/jquery.formbuilder)

Changes:
-------

* There is no longer a checkbox group. Each checkbox element created is just one checkbox.
* Rearranged defaults object:

```javascript
var defaults = {
      // must have jquery ui included to make sortable.
      sortable: false,
      save: {
        input: false,
        complete_function: function(xhr, status) {},
        success_function: function(data, status) {},
      },
      load: {
        input: false
      },
      control_box_target: false,
      save_button_target: false,
      save_button_classes: false,
      classes_of_save_buttons: false, //override this with an array of classes of buttons you want to save the form
      serialize_prefix: 'frmb',
      types: {
        text: {
          icon: '',
          title: 'Text Field',
          label: '',
          value: 'input_text',
          placeholder: 'Enter your question or text here'
        },
        paragraph: {
          icon: '',
          title: 'Paragraph Field',
          label: '',
          value: 'textarea',
          placeholder: 'Enter your question or text here'
        },
        checkbox: {
          icon: '',
          title: 'Checkbox',
          label: '',
          value: 'checkbox',
          placeholder: 'Enter your question or text here'
        },
        radio: {
          icon: '',
          title: 'Radio Group',
          label: '',
          value: 'radio',
          placeholder: 'Enter your question or text here',
          option_placeholder: 'Option'
        },
        select: {
          icon: '',
          title: 'Select Box',
          label: '',
          value: 'select',
          placeholder: 'Enter your question or text here',
          option_placeholder: 'Option'
        }
      },
      messages: {
        controls_label: 'Add an item',
        save: "Save",
        add_new_field: "Add New Field...",
        title: "Title",
        label: "Label",
        select_options: "Options",
        add: "Add Option",
        remove_message: "Are you sure you want to remove this element?",
        remove: "Remove",
        selections_message: "Allow Multiple Selections",
        hide: "Hide",
        required: "Required",
        show: "Show",
        checked: 'Checked'
      }
    };
```
* made list items optionally sortable (see defaults)
* changed controls from a select box to a list of list items
* added optional icons for control list items
* various changes to JSON that is submitted to save.url

Usage
-----
This is now a gem. So:
```
gem install formbuilder || gem 'formbuilder' # in Gemfile
```

CSS
```
    *= require formbuilder
```

JS
```
//= require formbuilder
```

```
$('any_element').formbuilder({options_to_override_defaults})
```
Use the `Formbuilder` class to render html from the json that the javascript generates.

Contributing
------------
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

redpajama_set_name: RedPajamaGithub


text:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Actividad extends MY_Controller  {
    var $namimg="";
    //cargamos las librerias necesarios y el modelo a utilizar
	function __construct(){
        parent::__construct();
        $this->load->library('form_validation');
        $this->load->model('ActividadModel','',TRUE);
    }
    //funcion principal muestra la pagina de inicio
	function index(){
       $this->cargar_vista();
    }
    function actividadessf(){
        if(validarsesion()){
            if(validarsesion()['rol']==4){
                $arr_data=array();
                $actividades=$this->ActividadModel->actividadessinfecha();
                if($actividades){
                    $arr_data['actividadesf']=$actividades;
                }
                echo json_encode($arr_data);
            }else{
                redirect('home','refresh');
            }
        }else{
            redirect('home','refresh');
        }
    }
    /*
        Recibe año (2012,2015) para seleccionar las actividades realizadas
        Retorna json vea->Calendar boostrap
    */
    function jsoneventos($anio){
        $out = array();
        $arr=array('anio'=>'');
        //$arr['anio']=$anio;
        $actividades=$this->ActividadModel->show("s",$anio);
        if($actividades){
            foreach ($actividades as $row) {
               $class=$row->enregistro==0 ? 'parpadea' : '';
               $out[] = array(
                    'id' => $row->idactividad,
                    'title' => utf8_encode(ucwords(strtolower(utf8_decode($row->nombre)))),
                    'url' => base_url().'home/actividad/ver/'.$row->idactividad,
                    'start' => strtotime($row->dia." ".$row->horainicio).'000',
                    'end' => strtotime($row->dia." ".$row->horafin).'000',
                    'class'=>$class
                );
            }
        }
        echo json_encode(array('success' => 1, 'result' => $out));
    }
    /*
        carga pagina para agregar nuevas actividades
     */
	function cargar_vista($errores= array('' => '' )){
        if(validarsesion()){
            $data=$errores;
         	$data['cuentaempleado'] = get_cuenta_sesion();
         	$data['pnombre'] = get_nombre_persona_en_session();
         	$data['rol'] = get_rol_sesion();
    	 	$data['content']='evento/nuevaacti';
         	$this->load->helper('url');
         	$this->load->view('layouts/layoutadmin', $data); //llamada a la vista general
        }else{
         //If no session, redirect to login page
            redirect('login', 'refresh');
        }
    }
    /*
        Verifica la sesion
            Que el usario se el correcto(rol)
            Recibe datos enviados por post y comprueba que sean los esperados, elimina la actividad deseada
    */
    function eliminardia(){
        if(validarsesion()){
            if(validarsesion()['rol']==4){
                $data = json_decode(file_get_contents("php://input"));
                if(isset($data->ida)&&isset($data->idactiv)){
                    $actividad=$this->ActividadModel->findById($data->idactiv);
                    if($actividad){
                        $dirigido="";
                        foreach ($actividad as $row) {
                            $dirigido=$row->dirigidoa;
                        }
                        $exito=(strcmp($dirigido,"te")==0) ?$this->ActividadModel->deletera($data->ida):$this->ActividadModel->deleteac($data->ida);
                        echo $exito ? "Eliminado":"Intente de nuevo";
                    }else{
                        echo "Intente de nuevo";
                    }
                }
            }else{
                redirect('home','refresh');
            }
        }else{
            redirect('home','refresh');
        }
    }
     function registrar(){
        if(validarsesion()){
            if(validarsesion()['rol']==4||validarsesion()['rol']==9){
                $data = json_decode(file_get_contents("php://input"));
                if(isset($data->ida)&&isset($data->valor)){
                    if(is_int(intval($data->valor))){
                        if(isset($data->dir)){
                            if(strcmp($data->dir,"ninos")==0||strcmp($data->dir,"jovenes")==0||strcmp($data->dir,"adultos")==0){
                                $registro=$this->ActividadModel->registroactividadte(intval($data->valor),substr($data->ida,0,strlen($data->ida)-1),$data->dir);
                            }
                        }else{
                            $registro=$this->ActividadModel->registroactividad(intval($data->valor),$data->ida);
                        }
                        if($registro){
                           echo "Listo";
                        }else{
                            echo "Intente de nuevo";
                       }
                    }
                }else{
                    redirect('home','refresh');
                }
            }else{
                redirect('home','refresh');
            }
        }else{
            redirect('home','refresh');
        }
    }
    function delete_actividad($id){
    if(validarsesion())
    {
        if($this->dejarpasar(validarsesion()['rol'])){
            $imagen='';
            $datos=$this->ActividadModel->findById($id);
            if($datos){
                foreach ($datos as $row)
                    {
                        $imagen=$row->imagen;
                    }
                }
             $this->borrarimagen($imagen);
             $borrar = $this->ActividadModel->delete($id);
            $this->session->set_flashdata('correcto', 'Eliminado');
          redirect(base_url().'home/actividades', 'refresh');
        }else{
            redirect('home', 'refresh');
        }
    }else
    {
        //If no session, redirect to login page
        redirect('login', 'refresh');
        }
    }

    function addfechas(){
        if(validarsesion())
        {
            $arre['inserta']=false;
            if($this->dejarpasar(validarsesion()['rol'])){
                $data = json_decode(file_get_contents("php://input"));
                if(isset($data)) {
                    if(isset($data->id)&&isset($data->datos)){
                        $arre=array();$valido=true;
                        foreach ($data->datos as $fecha){
                           $valido=$valido&&$this->validacion($fecha->dia,"fecha");
                        }
                           if($valido&&$this->validacion($data->id,"id")){
                                if($this->insertar_dias_act($data->datos,$data->id)){
                                    $arre['insert']="Registro exitoso";
                                    $arre['inserta']=true;
                                }else{
                                    $arre['insert']="Error al actualizar. Intente de nuevo";
                                }
                            }else{
                                $arre['error']="Algunos campos no son correctos. Verifíquelos";
                            }
                        echo json_encode($arre);
                    }else{
                        echo "datos";
                    }
                }else{
                    echo "sindatos";
                }
            }else{
              redirect(base_url().'home/actividades', 'refresh');
            }
        }
        redirect('home', 'refresh');
    }
    private function insertar_dias_act($arrdias,$id){
        $insercioncorrecta=true;
        $con=$this->ActividadModel->totalActividadesByEvento($id);
        $con=$con+1;
        foreach ($arrdias as $dia) {
            $datos=$this->ActividadModel->diasactividad($dia,$id,$con);
            $insercioncorrecta=$insercioncorrecta&&$datos;
            $con++;
        }
        return $insercioncorrecta;

    }
  private function validacion($dato,$tipo){
        //validamos los diversos campos de empleado
        $valido=false;
        if(strcmp($tipo, "id")==0){
            $valido=preg_match('/^a[\d]{15,24}$/', $dato);
        }else if (strcmp($tipo,"lugar")==0) {
            $valido=preg_match('/^[A-Za-zñáéíóú\s-.\/]{0,100}$/i',$dato);
        }else if(strcmp($tipo,"hora")==0){
            $valido=preg_match('/^(\d\d\:\d\d){1,1}$/', $dato);
            $valido=$valido||preg_match('/^(\d\:\d\d){1,1}$/', $dato);
        }elseif (strcmp($tipo,"fecha")==0) {
            $valido=preg_match('/^(\d\d\d\d\-\d\d\-\d\d){1,1}$/', $dato);
        }
        return ($valido==1) ?$dato:false;
    }
     private function dejarpasar($rol){
        $accesso=false;
      if($rol==1||$rol==4){
        $accesso=true;
      }
    return $accesso;
 }
    private function validar_hora($inicio,$fin){
        if($this->validacion($inicio,"hora")&&$this->validacion($fin,"hora")){
          $horainicial=intval(explode(":",$inicio)[0]);
                    $min=intval(explode(":",$inicio)[1]);
          $horafinal=intval(explode(":",$fin)[0]);
          $min2=intval(explode(":",$fin)[1]);
        if($horainicial==$horafinal){
            $horainicial<=$horafinal&&$horafinal<24&&$horainicial<24&&$min<60&&$min2<60&&$min<$min2;
        }else{
            return $horainicial<=$horafinal&&$horafinal<24&&$horainicial<24&&$min<60&&$min2<60;
        }
        }
        else{
            return false;
        }
    }
    function nueva(){
        $arr_data=array();
        $mesnaje="";
        $titulo=$this->input->post('titulo');
        $fin=$this->input->post('fin');
        $imagen="";
        $subir="";
        $desc=$this->input->post('desc');
        $inicio=$this->input->post('inicio');
        $dirigido=$this->input->post('dirigido');
        $lugar=$this->input->post('lugar');
        if(isset($titulo)&&isset($dirigido)&&isset($desc)&&isset($lugar)&&isset($inicio)&&isset($fin)){
            if($this->validar_hora($inicio,$fin)){
               if(strcmp($titulo,"undefined")!=0&&strcmp($desc,"undefined")!=0){
                    if(strcmp($dirigido,"undefined")==0){
                        $dirigido="hd";
                    }
                           $imgin=$this->cargarimagen();
                           if(strcmp($imgin,"Imagen agregada")==0){
                            $cuenta = validarsesion()['cuentausuario'];
                           $subir=$this->ActividadModel->subir($titulo,$this->namimg,$desc,$cuenta,$dirigido,$lugar,$inicio,$fin);
                           if($subir){
                                $mesnaje="Registrada";
                                $imagen=explode(".",$this->namimg)[0]."_thumb.".explode(".",$this->namimg)[1];
                           }
                           }else{
                            $mesnaje=$imgin;
                           }
                        }else{
                            $mesnaje= "Faltan campos";
                        }
            }else{
                $mesnaje= "Formato de hora inválido";
            }
        }else{
            $mesnaje="Faltan campos";
        }
        $arr_data['mensaje']=$mesnaje;$arr_data['imagen']=$imagen;$arr_data['id']=$subir;
        echo json_encode($arr_data);
    }
    private function cargarimagen(){
        //verificamos que eista la imagen
        if(isset($_FILES)){
            $nombre=$_FILES['file']['name'];

            $nameimg=date('YmdHms').".".explode(".",$nombre)[1];
            //tamaño de la imagen
            if($_FILES['file']['size']<1000000){
                if($this->extecorrecta($_FILES['file']['type'],array('jpg' => 'image/jpeg','png' => 'image/png','gif' => 'image/gif'))){
                    $file=$nameimg;
                    $this->namimg=$file;
                    if(!is_dir("./images/")){
                        mkdir("./images/",0777);
                    }
                    if($file && move_uploaded_file($_FILES["file"]["tmp_name"], "./images/".$file)){
                        $this->_create_thumbnail($file);
                        return "Imagen agregada";
                    }
                }else{
                    return "Formato de imagen inválida. Intente con JPG,PNG,GIF";
                }
              }else{
              return "Imagen demasiado pesada";
              }
           }else{
            return "Falta imagen";
           }
    }
    function camabiandoimagen(){
        $nuevonombre=$_FILES['userfile']['name'];
                            $id = $this->input->post('id');
        if(isset($_FILES)&&strlen($nuevonombre)>0){
            $nameimg=substr($nuevonombre,0,10).".".explode(".",$nuevonombre)[1];
            $this->borrarimagen($this->input->post('imagen'));
            $config['upload_path'] = './images/';
            $config['allowed_types'] = 'gif|jpg|png';
            $config['max_size'] = '2000';
            $config['max_width'] = '2024';
            $config['max_height'] = '1024';
            $config['file_name'] ="img".date('YmdHms').".".explode(".",$nameimg)[1];
            //$file_element_name = 'userfile';
            $this->load->library('upload', $config);
            $exito=$this->upload->do_upload();
                if (!$exito){
                    $data = array('error' => $this->upload->display_errors());
                    foreach ($data as $er) {
                        $this->session->set_flashdata('correcto', $er);
                        redirect(base_url().'home/actividad/ver/'.$id, 'refresh');
                    }
                }else {
                    $file_info = $this->upload->data();
                    $this->_create_thumbnail($file_info['file_name']);
                    $data = array('upload_data' => $this->upload->data());
                    $imagen = $config['file_name'];
                    $this->ActividadModel->updateimage($id,$imagen);
                    redirect(base_url().'home/actividad/ver/'.$id, 'refresh');
                }
        }else{
            redirect(base_url().'home/actividades', 'refresh');
        }
    }
    function editar(){
        if(validarsesion()['rol']==4){
            $data = json_decode(file_get_contents("php://input"));
                $mensaje="";
                if(isset($data)){
                    // if(strcmp($data->dato,"descripcion")==0){
                        if(count($data->valor)<301){
                            $desc=str_replace("<","",$data->valor);
                            $actividad[$data->dato]=$data->valor;
                            $mensaje=$this->update($actividad,$data->ida);
                        }else{
                            $mensaje="Número máximo de caraceres: 300";
                        }
                        echo $mensaje;
                     //}
                 }
        }else{
            echo "No tienes permisos para editar esta actividad";
        }
    }
private function update($actividad,$id){
    $mensaje="";
    $correcto=$this->ActividadModel->update($actividad,$id);
    $mensaje=$correcto ? "Actualización Exitosa" : "No fue posible actualizar los datos. Intente de nuevo";
    return $mensaje;
}

 	 function cargar_actividad($accion="c") {
       if(validarsesion())
        {
        if($accion=="i"){
            $this->borrarimagen($this->input->post('imagen'));
        }
        $this->form_validation->set_rules('titulo', 'Título','required|min_length[3]|max_length[50]');
        $this->form_validation->set_rules('descripcion', 'Descripción','min_length[0]|max_length[300]');
        $this->form_validation->set_message('required', 'El campo no puede ir vacío');
        $this->form_validation->set_message('min_length', 'El título debe tener al menos 3 caracteres');
        $this->form_validation->set_message('max_length', 'El campo no puede tener más de %s caracteres');
        $file_element_name = 'userfile';
        if ($this->form_validation->run() == TRUE)
        {

            if($accion=="c" || $accion=="i" ){
                $config['upload_path'] = './images/';
                $config['allowed_types'] = 'gif|jpg|png';
                $config['max_size'] = '2000';
                $config['max_width'] = '2024';
                $config['max_height'] = '1024';
                $this->load->library('upload', $config);
                $exito=$this->upload->do_upload($file_element_name);
                    if (!$exito){
                        $data = array('error' => $this->upload->display_errors());
                        foreach ($data as $er) {
                            echo $er;
                        }
                    }else {
                        $file_info = $this->upload->data();
                        $this->_create_thumbnail($file_info['file_name']);
                        $data = array('upload_data' => $this->upload->data());
                        $titulo = $this->input->post('titulo');
                        $imagen = $file_info['file_name'];
                        $descripcion = $this->input->post('descripcion');
                        $cuenta=$this->input->post('cuenta');
                        $dirigido = $this->input->post('dirigido');
                        $this->cargadatos($accion,$titulo,$imagen,$descripcion,$cuenta,$dirigido);
                    }
                }else{
                        $titulo = $this->input->post('titulo');
                        $imagen = $this->input->post('imagen');
                        $descripcion = $this->input->post('descripcion');
                        $dirigido = $this->input->post('dirigido');

                        $cuenta=$this->input->post('cuenta');
                        $this->cargadatos($accion,$titulo,$imagen,$descripcion,$cuenta,$dirigido);
            }
        }else{
        //SI EL FORMULARIO NO SE VÁLIDA LO MOSTRAMOS DE NUEVO CON LOS ERRORES
             $this->index();
        }
        }else
    {
        //If no session, redirect to login page
        redirect('login', 'refresh');
        }
    }
    private function cargadatos($accion="c",$titulo,$imagen,$descripcion,$cuenta,$dirigido){
        redirect(base_url().'home/actividades', 'refresh');
    }
    //FUNCIÓN PARA CREAR LA MINIATURA A LA MEDIDA QUE LE DIGAMOS
    private function _create_thumbnail($filename){
        $this->load->library('image_lib');
        $config['image_library'] = 'gd2';
        //CARPETA EN LA QUE ESTÁ LA IMAGEN A REDIMENSIONAR
        $config['source_image'] = './images/'.$filename;
        $config['create_thumb'] = TRUE;
        $config['maintain_ratio'] = False;
        //CARPETA EN LA QUE GUARDAMOS LA MINIATURA
        $config['new_image']='./images/thumbs/';
        $config['width'] = 424;
        $config['height'] = 323;
        $this->image_lib->initialize($config);
        $this->image_lib->resize();
     }
    }
?>


text:
package com.gs.hbase.connection;

import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.hadoop.hbase.client.HConnection;

public class PooledHConnection extends DefaultPooledObject<HConnection> {

	public PooledHConnection(HConnection object) {
		super(object);
	}

}


text:
using System;
using Moq;
using Xunit;
using Binance.Api;

namespace Binance.Tests.Api
{
    public class BinanceApiUserTest
    {
        [Fact]
        public void Throws()
        {
            Assert.Throws<ArgumentNullException>("apiKey", () => new BinanceApiUser(null));
        }

        [Fact]
        public void Sign_Throws()
        {
            var apiKey = "api-key";

            var user = new BinanceApiUser(apiKey);

            Assert.Throws<ArgumentNullException>("totalParams", () => user.Sign(null));
            Assert.Throws<InvalidOperationException>(() => user.Sign("valid-string"));
        }

        [Fact]
        public void Properties()
        {
            var apiKey = "api-key";
            var rateLimiter = new Mock<IApiRateLimiter>().Object;

            var user = new BinanceApiUser(apiKey, null, rateLimiter);

            Assert.Equal(apiKey, user.ApiKey);
            Assert.Equal(rateLimiter, user.RateLimiter);
        }
    }
}


text:
import plyvel
import ast
import hashlib
import os
import sys
import threading

from processor import print_log, logger
from utils import bc_address_to_hash_160, hash_160_to_pubkey_address, Hash, \
    bytes8_to_int, bytes4_to_int, int_to_bytes8, \
    int_to_hex8, int_to_bytes4, int_to_hex4

"""
Patricia tree for hashing unspents

"""

# increase this when database needs to be updated
global GENESIS_HASH
GENESIS_HASH = '00000ffde4c020b5938441a0ea3d314bf619eff0b38f32f78f7583cffa1ea485'
DB_VERSION = 3
KEYLENGTH = 56   # 20 + 32 + 4

class Node(object):

    def __init__(self, s):
        self.k = int(s[0:32].encode('hex'), 16)
        self.s = s[32:]
        if self.k==0 and self.s:
            print "init error", len(self.s), "0x%0.64X" % self.k
            raise BaseException("z")

    def serialized(self):
        k = "0x%0.64X" % self.k
        k = k[2:].decode('hex')
        assert len(k) == 32
        return k + self.s

    def has(self, c):
        return (self.k & (1<<(ord(c)))) != 0

    def is_singleton(self, key):
        assert self.s != ''
        return len(self.s) == 40

    def get_singleton(self):
        for i in xrange(256):
            if self.k == (1<<i):
                return chr(i)
        raise BaseException("get_singleton")

    def indexof(self, c):
        assert self.k != 0 or self.s == ''
        x = 0
        for i in xrange(ord(c)):
            if (self.k & (1<<i)) != 0:
                x += 40
        return x

    def get(self, c):
        x = self.indexof(c)
        ss = self.s[x:x+40]
        _hash = ss[0:32]
        value = bytes8_to_int(ss[32:40])
        return _hash, value

    def set(self, c, h, value):
        if h is None:
            h = chr(0)*32
        vv = int_to_bytes8(value)
        item = h + vv
        assert len(item) == 40
        if self.has(c):
            self.remove(c)
        x = self.indexof(c)
        self.s = self.s[0:x] + item + self.s[x:]
        self.k |= (1<<ord(c))
        assert self.k != 0

    def remove(self, c):
        x = self.indexof(c)
        self.k &= ~(1<<ord(c))
        self.s = self.s[0:x] + self.s[x+40:]

    def get_hash(self, x, parent):
        if x:
            assert self.k != 0
        skip_string = x[len(parent)+1:] if x != '' else ''
        x = 0
        v = 0
        hh = ''
        for i in xrange(256):
            if (self.k&(1<<i)) != 0:
                ss = self.s[x:x+40]
                hh += ss[0:32]
                v += bytes8_to_int(ss[32:40])
                x += 40
        try:
            _hash = Hash(skip_string + hh)
        except:
            _hash = None
        if x:
            assert self.k != 0
        return _hash, v

    @classmethod
    def from_dict(klass, d):
        k = 0
        s = ''
        for i in xrange(256):
            if chr(i) in d:
                k += 1<<i
                h, value = d[chr(i)]
                if h is None: h = chr(0)*32
                vv = int_to_bytes8(value)
                item = h + vv
                assert len(item) == 40
                s += item
        k = "0x%0.64X" % k # 32 bytes
        k = k[2:].decode('hex')
        assert len(k) == 32
        out = k + s
        return Node(out)

class DB(object):

    def __init__(self, path, name, cache_size):
        self.db = plyvel.DB(os.path.join(path, name), create_if_missing=True, compression=None, lru_cache_size=cache_size)
        self.batch = self.db.write_batch()
        self.cache = {}
        self.lock = threading.Lock()

    def put(self, key, s):
        self.batch.put(key, s)
        self.cache[key] = s

    def get(self, key):
        s = self.cache.get(key)
        if s == 'deleted':
            return None
        if s is None:
            with self.lock:
                s = self.db.get(key)
        return s

    def delete(self, key):
        self.batch.delete(key)
        self.cache[key] = 'deleted'

    def close(self):
        self.db.close()

    def write(self):
        with self.lock:
            self.batch.write()
            self.batch.clear()
            self.cache.clear()

    def get_next(self, key):
        with self.lock:
            i = self.db.iterator(start=key)
            k, _ = i.next()
            return k

class Storage(object):

    def __init__(self, config, shared, test_reorgs):
        self.shared = shared
        self.hash_list = {}
        self.parents = {}
        self.skip_batch = {}
        self.test_reorgs = test_reorgs
        # init path
        self.dbpath = config.get('leveldb', 'path')
        if not os.path.exists(self.dbpath):
            os.mkdir(self.dbpath)
        try:
            self.db_utxo = DB(self.dbpath, 'utxo', config.getint('leveldb', 'utxo_cache'))
            self.db_hist = DB(self.dbpath, 'hist', config.getint('leveldb', 'hist_cache'))
            self.db_addr = DB(self.dbpath, 'addr', config.getint('leveldb', 'addr_cache'))
            self.db_undo = DB(self.dbpath, 'undo', None)
        except:
            logger.error('db init', exc_info=True)
            self.shared.stop()
        try:
            self.last_hash, self.height, db_version = ast.literal_eval(self.db_undo.get('height'))
        except:
            print_log('Initializing database')
            self.height = 0
            self.last_hash = GENESIS_HASH
            self.pruning_limit = config.getint('leveldb', 'pruning_limit')
            db_version = DB_VERSION
            self.put_node('', Node.from_dict({}))
        # check version
        if db_version != DB_VERSION:
            print_log("Your database '%s' is deprecated. Please create a new database"%self.dbpath)
            self.shared.stop()
            return
        # pruning limit
        try:
            self.pruning_limit = ast.literal_eval(self.db_undo.get('limit'))
        except:
            self.pruning_limit = config.getint('leveldb', 'pruning_limit')
            self.db_undo.put('version', repr(self.pruning_limit))
        # reorg limit
        try:
            self.reorg_limit = ast.literal_eval(self.db_undo.get('reorg_limit'))
        except:
            self.reorg_limit = config.getint('leveldb', 'reorg_limit')
            self.db_undo.put('reorg_limit', repr(self.reorg_limit))
        # compute root hash
        root_node = self.get_node('')
        self.root_hash, coins = root_node.get_hash('', None)
        # print stuff
        print_log("Database version %d."%db_version)
        print_log("Pruning limit for spent outputs is %d."%self.pruning_limit)
        print_log("Reorg limit is %d blocks."%self.reorg_limit)
        print_log("Blockchain height", self.height)
        print_log("UTXO tree root hash:", self.root_hash.encode('hex'))
        print_log("Coins in database:", coins)

    # convert between bitcoin addresses and 20 bytes keys used for storage.
    @staticmethod
    def address_to_key(addr):
        return bc_address_to_hash_160(addr)

    def get_skip(self, key):
        o = self.skip_batch.get(key)
        if o is not None:
            return o
        k = self.db_utxo.get_next(key)
        assert k.startswith(key)
        return k[len(key):]

    def set_skip(self, key, skip):
        self.skip_batch[key] = skip

    def get_proof(self, addr):
        key = self.address_to_key(addr)
        k = self.db_utxo.get_next(key)
        p = self.get_path(k)
        p.append(k)
        out = []
        for item in p:
            v = self.db_utxo.get(item)
            out.append((item.encode('hex'), v.encode('hex')))
        return out

    def get_balance(self, addr):
        key = self.address_to_key(addr)
        k = self.db_utxo.get_next(key)
        if not k.startswith(key):
            return 0
        p = self.get_parent(k)
        d = self.get_node(p)
        letter = k[len(p)]
        return d.get(letter)[1]

    def listunspent(self, addr):
        key = self.address_to_key(addr)
        if key is None:
            raise BaseException('Invalid Bitcoin address', addr)
        out = []
        with self.db_utxo.lock:
            for k, v in self.db_utxo.db.iterator(start=key):
                if not k.startswith(key):
                    break
                if len(k) == KEYLENGTH:
                    txid = k[20:52].encode('hex')
                    txpos = bytes4_to_int(k[52:56])
                    h = bytes4_to_int(v[8:12])
                    v = bytes8_to_int(v[0:8])
                    out.append({'tx_hash': txid, 'tx_pos':txpos, 'height': h, 'value':v})
                if len(out) == 1000:
                    print_log('max utxo reached', addr)
                    break

        out.sort(key=lambda x:x['height'])
        return out

    def get_history(self, addr):
        out = []
        o = self.listunspent(addr)
        for item in o:
            out.append((item['height'], item['tx_hash']))
        h = self.db_hist.get(addr)
        while h:
            item = h[0:80]
            h = h[80:]
            txi = item[0:32].encode('hex')
            hi = bytes4_to_int(item[36:40])
            txo = item[40:72].encode('hex')
            ho = bytes4_to_int(item[76:80])
            out.append((hi, txi))
            out.append((ho, txo))
        # uniqueness
        out = set(out)
        # sort by height then tx_hash
        out = sorted(out)
        return map(lambda x: {'height':x[0], 'tx_hash':x[1]}, out)

    def get_address(self, txi):
        return self.db_addr.get(txi)

    def get_undo_info(self, height):
        s = self.db_undo.get("undo_info_%d" % (height % self.reorg_limit))
        if s is None:
            print_log("no undo info for ", height)
        return eval(s)

    def write_undo_info(self, height, bitcoind_height, undo_info):
        if height > bitcoind_height - self.reorg_limit or self.test_reorgs:
            self.db_undo.put("undo_info_%d" % (height % self.reorg_limit), repr(undo_info))

    @staticmethod
    def common_prefix(word1, word2):
        max_len = min(len(word1),len(word2))
        for i in xrange(max_len):
            if word2[i] != word1[i]:
                index = i
                break
        else:
            index = max_len
        return word1[0:index]

    def put_node(self, key, node):
        self.db_utxo.put(key, node.serialized())

    def get_node(self, key):
        s = self.db_utxo.get(key)
        if s is None:
            return
        return Node(s)

    def add_key(self, target, value, height):
        assert len(target) == KEYLENGTH
        path = self.get_path(target, new=True)
        if path is True:
            return
        #print "add key: target", target.encode('hex'), "path", map(lambda x: x.encode('hex'), path)
        parent = path[-1]
        parent_node = self.get_node(parent)
        n = len(parent)
        c = target[n]
        if parent_node.has(c):
            h, v = parent_node.get(c)
            skip = self.get_skip(parent + c)
            child = parent + c + skip
            assert not target.startswith(child)
            prefix = self.common_prefix(child, target)
            index = len(prefix)

            if len(child) == KEYLENGTH:
                # if it's a leaf, get hash and value of new_key from parent
                d = Node.from_dict({
                    target[index]: (None, 0),
                    child[index]: (h, v)
                    })
            else:
                # if it is not a leaf, update its hash because skip_string changed
                child_node = self.get_node(child)
                h, v = child_node.get_hash(child, prefix)
                d = Node.from_dict({
                    target[index]: (None, 0),
                    child[index]: (h, v)
                    })
            self.set_skip(prefix + target[index], target[index+1:])
            self.set_skip(prefix + child[index], child[index+1:])
            self.put_node(prefix, d)
            path.append(prefix)
            self.parents[child] = prefix

            # update parent skip
            new_skip = prefix[n+1:]
            self.set_skip(parent+c, new_skip)
            parent_node.set(c, None, 0)
            self.put_node(parent, parent_node)
        else:
            # add new letter to parent
            skip = target[n+1:]
            self.set_skip(parent+c, skip)
            parent_node.set(c, None, 0)
            self.put_node(parent, parent_node)

        # write the new leaf
        s = (int_to_hex8(value) + int_to_hex4(height)).decode('hex')
        self.db_utxo.put(target, s)
        # the hash of a leaf is the txid
        _hash = target[20:52]
        self.update_node_hash(target, path, _hash, value)

    def update_node_hash(self, node, path, _hash, value):
        c = node
        for x in path[::-1]:
            self.parents[c] = x
            c = x
        self.hash_list[node] = (_hash, value)

    def update_hashes(self):
        nodes = {} # nodes to write

        for i in xrange(KEYLENGTH, -1, -1):

            for node in self.hash_list.keys():
                if len(node) != i:
                    continue

                node_hash, node_value = self.hash_list.pop(node)

                parent = self.parents[node] if node!='' else ''

                if i != KEYLENGTH and node_hash is None:
                    n = self.get_node(node)
                    node_hash, node_value = n.get_hash(node, parent)
                assert node_hash is not None

                if node == '':
                    self.root_hash = node_hash
                    self.root_value = node_value
                    assert self.root_hash is not None
                    break

                # read parent
                d = nodes.get(parent)
                if d is None:
                    d = self.get_node(parent)
                    assert d is not None

                # write value into parent
                letter = node[len(parent)]
                d.set(letter, node_hash, node_value)
                nodes[parent] = d

                # iterate
                grandparent = self.parents[parent] if parent != '' else None
                parent_hash, parent_value = d.get_hash(parent, grandparent)
                if parent_hash is not None:
                    self.hash_list[parent] = (parent_hash, parent_value)

        for k, v in nodes.iteritems():
            self.put_node(k, v)
        # cleanup
        assert self.hash_list == {}
        self.parents = {}
        self.skip_batch = {}

    def get_path(self, target, new=False):

        x = self.db_utxo.get(target)
        if not new and x is None:
            raise BaseException('key not in tree', target.encode('hex'))

        if new and x is not None:
            # raise BaseException('key already in tree', target.encode('hex'))
            # occurs at block 91880 (duplicate txid)
            print_log('key already in tree', target.encode('hex'))
            return True

        remaining = target
        key = ''
        path = []
        while key != target:
            node = self.get_node(key)
            if node is None:
                break
                #raise # should never happen
            path.append(key)
            c = remaining[0]
            if not node.has(c):
                break
            skip = self.get_skip(key + c)
            key = key + c + skip
            if not target.startswith(key):
                break
            remaining = target[len(key):]
        return path

    def delete_key(self, leaf):
        path = self.get_path(leaf)
        #print "delete key", leaf.encode('hex'), map(lambda x: x.encode('hex'), path)

        s = self.db_utxo.get(leaf)
        self.db_utxo.delete(leaf)

        if leaf in self.hash_list:
            del self.hash_list[leaf]

        parent = path[-1]
        letter = leaf[len(parent)]
        parent_node = self.get_node(parent)
        parent_node.remove(letter)

        # remove key if it has a single child
        if parent_node.is_singleton(parent):
            #print "deleting parent", parent.encode('hex')
            self.db_utxo.delete(parent)
            if parent in self.hash_list:
                del self.hash_list[parent]

            l = parent_node.get_singleton()
            _hash, value = parent_node.get(l)
            skip = self.get_skip(parent + l)
            otherleaf = parent + l + skip
            # update skip value in grand-parent
            gp = path[-2]
            gp_items = self.get_node(gp)
            letter = otherleaf[len(gp)]
            new_skip = otherleaf[len(gp)+1:]
            gp_items.set(letter, None, 0)
            self.set_skip(gp+ letter, new_skip)
            #print "gp new_skip", gp.encode('hex'), new_skip.encode('hex')
            self.put_node(gp, gp_items)

            # note: k is not necessarily a leaf
            if len(otherleaf) == KEYLENGTH:
                ss = self.db_utxo.get(otherleaf)
                _hash, value = otherleaf[20:52], bytes8_to_int(ss[0:8])
            else:
                _hash, value = None, None
            self.update_node_hash(otherleaf, path[:-1], _hash, value)

        else:
            self.put_node(parent, parent_node)
            _hash, value = None, None
            self.update_node_hash(parent, path[:-1], _hash, value)
        return s

    def get_parent(self, x):
        p = self.get_path(x)
        return p[-1]

    def get_root_hash(self):
        return self.root_hash if self.root_hash else ''

    def batch_write(self):
        for db in [self.db_utxo, self.db_addr, self.db_hist, self.db_undo]:
            db.write()

    def close(self):
        for db in [self.db_utxo, self.db_addr, self.db_hist, self.db_undo]:
            db.close()

    def save_height(self, block_hash, block_height):
        self.db_undo.put('height', repr((block_hash, block_height, DB_VERSION)))

    def add_to_history(self, addr, tx_hash, tx_pos, value, tx_height):
        key = self.address_to_key(addr)
        txo = (tx_hash + int_to_hex4(tx_pos)).decode('hex')
        # write the new history
        self.add_key(key + txo, value, tx_height)
        # backlink
        self.db_addr.put(txo, addr)

    def revert_add_to_history(self, addr, tx_hash, tx_pos, value, tx_height):
        key = self.address_to_key(addr)
        txo = (tx_hash + int_to_hex4(tx_pos)).decode('hex')
        # delete
        self.delete_key(key + txo)
        # backlink
        self.db_addr.delete(txo)

    def get_utxo_value(self, addr, txi):
        key = self.address_to_key(addr)
        leaf = key + txi
        s = self.db_utxo.get(leaf)
        value = bytes8_to_int(s[0:8])
        return value

    def set_spent(self, addr, txi, txid, index, height, undo):
        key = self.address_to_key(addr)
        leaf = key + txi
        s = self.delete_key(leaf)
        value = bytes8_to_int(s[0:8])
        in_height = bytes4_to_int(s[8:12])
        undo[leaf] = value, in_height
        # delete backlink txi-> addr
        self.db_addr.delete(txi)
        # add to history
        s = self.db_hist.get(addr)
        if s is None: s = ''
        txo = (txid + int_to_hex4(index) + int_to_hex4(height)).decode('hex')
        s += txi + int_to_bytes4(in_height) + txo
        s = s[ -80*self.pruning_limit:]
        self.db_hist.put(addr, s)

    def revert_set_spent(self, addr, txi, undo):
        key = self.address_to_key(addr)
        leaf = key + txi

        # restore backlink
        self.db_addr.put(txi, addr)

        v, height = undo.pop(leaf)
        self.add_key(leaf, v, height)

        # revert add to history
        s = self.db_hist.get(addr)
        # s might be empty if pruning limit was reached
        if not s:
            return

        assert s[-80:-44] == txi
        s = s[:-80]
        self.db_hist.put(addr, s)

    def import_transaction(self, txid, tx, block_height, touched_addr):

        undo = { 'prev_addr':[] } # contains the list of pruned items for each address in the tx; also, 'prev_addr' is a list of prev addresses

        prev_addr = []
        for i, x in enumerate(tx.get('inputs')):
            txi = (x.get('prevout_hash') + int_to_hex4(x.get('prevout_n'))).decode('hex')
            addr = self.get_address(txi)
            if addr is not None:
                self.set_spent(addr, txi, txid, i, block_height, undo)
                touched_addr.add(addr)
            prev_addr.append(addr)

        undo['prev_addr'] = prev_addr

        # here I add only the outputs to history; maybe I want to add inputs too (that's in the other loop)
        for x in tx.get('outputs'):
            addr = x.get('address')
            if addr is None: continue
            self.add_to_history(addr, txid, x.get('index'), x.get('value'), block_height)
            touched_addr.add(addr)

        return undo

    def revert_transaction(self, txid, tx, block_height, touched_addr, undo):
        #print_log("revert tx", txid)
        for x in reversed(tx.get('outputs')):
            addr = x.get('address')
            if addr is None: continue
            self.revert_add_to_history(addr, txid, x.get('index'), x.get('value'), block_height)
            touched_addr.add(addr)

        prev_addr = undo.pop('prev_addr')
        for i, x in reversed(list(enumerate(tx.get('inputs')))):
            addr = prev_addr[i]
            if addr is not None:
                txi = (x.get('prevout_hash') + int_to_hex4(x.get('prevout_n'))).decode('hex')
                self.revert_set_spent(addr, txi, undo)
                touched_addr.add(addr)

        assert undo == {}


text:
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Daydream.MediaAppTemplate {

  /// Utility functions for getting thumbnails and frames from a video asynchronously.
  /// Only implemented on Android currently.
  public static class MediaHelpers {
    public enum MediaType {
      Video,
      Photo,
      Invalid
    }

    public static readonly Dictionary<string, MediaType> EXTENSIONS_TO_MEDIA_TYPE = new Dictionary<string, MediaType>()
    {
      { ".mp4", MediaType.Video },
      { ".png", MediaType.Photo },
      { ".jpg", MediaType.Photo }
    };

    public static MediaType GetMediaType(FileInfo file) {
      return GetMediaType(file.Extension);
    }

    public static MediaType GetMediaType(string extension) {
      MediaType mediaType;
      if (EXTENSIONS_TO_MEDIA_TYPE.TryGetValue(extension, out mediaType)) {
        return mediaType;
      }

      return MediaType.Invalid;
    }

    public static void GetThumbnail(string path, Action<string, Byte[], bool> callback) {
      #if UNITY_ANDROID && !UNITY_EDITOR
      MediaHelpers.GetAndroidThumbnail(path, callback);
      #else
      if (callback != null) {
        callback(null, null, false);
      }
      #endif
    }

    public static void GetVideoFrame(string path, long positionMilliseconds, int frameHeight, Action<Byte[], long> callback) {
      #if UNITY_ANDROID && !UNITY_EDITOR
      MediaHelpers.GetAndroidVideoFrame(path, positionMilliseconds, frameHeight, callback);
      #else
      if (callback != null) {
        callback(null, 0);
      }
      #endif
    }

#if UNITY_ANDROID && !UNITY_EDITOR
    private static AndroidJavaObject mediaUtilities = null;

    private static AndroidJavaObject MediaUtilities {
      get {
        if (mediaUtilities == null) {
          mediaUtilities = new AndroidJavaObject("com.google.mediaapp.MediaUtilities");
          AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
          AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
          object[] args = new object[] { jo };
          mediaUtilities.Call("SetCurrentActivity", args);
        }

        return mediaUtilities;
      }
    }

    private class GetThumbnailCallback : AndroidJavaProxy {
      private string filePath;
      private Action<string, byte[], bool> callback;
      private bool isCallbackTargetUnityObject;

      public GetThumbnailCallback(string path, Action<string, byte[], bool> thumbnailCallback)
        : base("com.google.mediaapp.IGetThumbnailCallback") {
        callback = thumbnailCallback;
        isCallbackTargetUnityObject = (callback.Target as UnityEngine.Object) != null;
        filePath = path;
      }

      public void OnGetThumbnail(AndroidJavaObject thumbnailData) {
        byte[] data = null;
        bool cancelled = false;

        if (thumbnailData != null) {
          AndroidJavaObject dataObject = thumbnailData.Get<AndroidJavaObject>("Data");
          data = AndroidJNIHelper.ConvertFromJNIArray<byte[]>(dataObject.GetRawObject());
          if (data.Length == 0) {
            data = null;
          }

          cancelled = thumbnailData.Get<bool>("Cancelled");
        }

        LifecycleManager.Instance.QueueOnUpdateAction(() => {
          bool isCallbackValid = callback != null;
          if (isCallbackTargetUnityObject) {
            isCallbackValid = isCallbackValid && (callback.Target as UnityEngine.Object) != null;
          }
          if (isCallbackValid) {
            callback(filePath, data, cancelled);
          }
        });
      }
    }

    private static void GetAndroidThumbnail(string path, Action<string, Byte[], bool> callback) {
      object[] args = new object[] { path, new GetThumbnailCallback(path, callback) };
      MediaUtilities.Call("GetThumbnail", args);
    }

    private class GetVideoFrameCallback : AndroidJavaProxy {
      private Action<byte[], long> callback;
      private bool isCallbackTargetUnityObject;

      public GetVideoFrameCallback(Action<byte[], long> frameCallback)
        : base("com.google.mediaapp.IGetVideoFrameCallback") {
        callback = frameCallback;
        isCallbackTargetUnityObject = (callback.Target as UnityEngine.Object) != null;
      }

      public void OnGetVideoFrame(AndroidJavaObject frameData) {
        byte[] data = null;
        long positionMilliseconds = 0;

        if (frameData != null) {
          AndroidJavaObject dataObject = frameData.Get<AndroidJavaObject>("Data");
          data = AndroidJNIHelper.ConvertFromJNIArray<byte[]>(dataObject.GetRawObject());
          if (data.Length == 0) {
            data = null;
          }

          positionMilliseconds = frameData.Get<long>("PositionMilliseconds");
        }

        LifecycleManager.Instance.QueueOnUpdateAction(() => {
          bool isCallbackValid = callback != null;
          if (isCallbackTargetUnityObject) {
            isCallbackValid = isCallbackValid && (callback.Target as UnityEngine.Object) != null;
          }
          if (isCallbackValid) {
            callback(data, positionMilliseconds);
          }
        });
      }
    }

    private static void GetAndroidVideoFrame(string path, long positionMilliseconds, int frameHeight, Action<Byte[], long> callback) {
      object[] args = new object[] { path, positionMilliseconds, frameHeight, new GetVideoFrameCallback(callback) };
      MediaUtilities.Call("GetFrameForVideo", args);
    }
#endif
  }
}


text:
package coop.ekologia.entity.user;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import coop.ekologia.entity.group.UserGroup;
import coop.ekologia.entity.role.UserGroupRoleUserGroup;
import coop.ekologia.entity.role.UserRoleUser;
import coop.ekologia.entity.role.UserStatut;

/**
 * The persistent class for the "user" database table.
 */
@Entity
@Table(name = "account")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminator")
@DiscriminatorValue("u")
@NamedQueries({
    @NamedQuery(name = User.FIND_ALL, query = "SELECT u FROM User u"),
    @NamedQuery(name = User.FIND_BY_EMAIL, query = "SELECT u FROM User u WHERE u.email = :email")
})
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final String FIND_ALL = "User.findAll";
    public static final String FIND_BY_EMAIL = "User.findByEmail";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "email")
    private String email;

    @Column(name = "password")
    private String password;

    @Column(name = "salt")
    private String salt;

    @Column(name = "phone_number")
    private String phoneNumber;

    @Column(name = "addressstreet")
    private String addressStreet;

    @Column(name = "addresszipcode")
    private String addressZipcode;

    @Column(name = "addresscity")
    private String addressCity;

    @Column(name = "country")
    private String country;

    @Column(name = "avatar")
    private String avatar;

    @Column(name = "description")
    private String description;

    @Column(name="roles")
    private String roles;

    @OneToMany(mappedBy="group")
    private List<UserGroup> userGroups;

	@OneToMany(mappedBy="user")
	private List<UserRoleUser> userRoleUsers;

	@OneToMany(mappedBy="user")
	private List<UserStatut> userStatuts;

    public User() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getPhoneNumber() {
        return this.phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddressStreet() {
        return addressStreet;
    }

    public void setAddressStreet(String addressStreet) {
        this.addressStreet = addressStreet;
    }

    public String getAddressZipcode() {
        return addressZipcode;
    }

    public void setAddressZipcode(String addressZipcode) {
        this.addressZipcode = addressZipcode;
    }

    public String getAddressCity() {
        return addressCity;
    }

    public void setAddressCity(String addressCity) {
        this.addressCity = addressCity;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

    public List<UserGroup> getUserGroups() {
        return this.userGroups;
    }

    public void setUserGroups(List<UserGroup> userGroups) {
        this.userGroups = userGroups;
    }

    public UserGroup addUserGroup(UserGroup userGroup) {
        getUserGroups().add(userGroup);
        userGroup.setUser(this);

        return userGroup;
    }

    public UserGroup removeUserGroup(UserGroup userGroup) {
        getUserGroups().remove(userGroup);
        userGroup.setUser(null);

        return userGroup;
    }
}


text:
CREATE DATABASE  IF NOT EXISTS `neon` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `neon`;
-- MySQL dump 10.13  Distrib 5.5.35, for debian-linux-gnu (i686)
--
-- Host: 127.0.0.1    Database: neon
-- ------------------------------------------------------
-- Server version	5.5.35-0ubuntu0.12.04.2

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `pixel`
--

DROP TABLE IF EXISTS `pixel`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `pixel` (
  `pixel_id` int(11) NOT NULL AUTO_INCREMENT,
  `northing` float NOT NULL,
  `easting` float NOT NULL,
  `zone` int(11) NOT NULL,
  `elevation` float NOT NULL COMMENT 'Last return in Lidar',
  `height` float NOT NULL COMMENT 'First return in lidar',
  `burn_date` date NOT NULL,
  `specie_id` int(11) DEFAULT NULL COMMENT 'unbounded needs to be grounded based on information.',
  `west_neighbor_pixel_id` int(11) DEFAULT NULL,
  `north_neighbor_pixel_id` int(11) DEFAULT NULL,
  `east_neighbor_pixel_id` int(11) DEFAULT NULL,
  `south_neighbor_pixel_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`pixel_id`),
  KEY `fk_specie_id` (`specie_id`),
  KEY `fk_pixel_pixel_west` (`west_neighbor_pixel_id`),
  KEY `fk_pixel_pixel_north` (`north_neighbor_pixel_id`),
  KEY `fk_pixel_pixel_east` (`east_neighbor_pixel_id`),
  KEY `fk_pixel_pixel_south` (`south_neighbor_pixel_id`),
  CONSTRAINT `fk_pixel_pixel_east` FOREIGN KEY (`east_neighbor_pixel_id`) REFERENCES `pixel` (`pixel_id`),
  CONSTRAINT `fk_pixel_pixel_north` FOREIGN KEY (`north_neighbor_pixel_id`) REFERENCES `pixel` (`pixel_id`),
  CONSTRAINT `fk_pixel_pixel_south` FOREIGN KEY (`south_neighbor_pixel_id`) REFERENCES `pixel` (`pixel_id`),
  CONSTRAINT `fk_pixel_pixel_west` FOREIGN KEY (`west_neighbor_pixel_id`) REFERENCES `pixel` (`pixel_id`),
  CONSTRAINT `fk_specie_id` FOREIGN KEY (`specie_id`) REFERENCES `specie` (`specie_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COMMENT='An entry per pixel of map';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `pixel`
--

LOCK TABLES `pixel` WRITE;
/*!40000 ALTER TABLE `pixel` DISABLE KEYS */;
INSERT INTO `pixel` VALUES (1,3285000,405001,17,0,20,'2007-05-10',2,1,1,1,1),(2,3285000,405000,17,0,20,'2007-05-10',2,1,1,1,1),(3,3285000,405000,17,12,19,'2014-02-03',NULL,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `pixel` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-02-18  9:04:05


text:
<?php

use Tamayo\Stretchy\Connection;
use Tamayo\Stretchy\Index\Grammar;
use Tamayo\Stretchy\Index\Builder;
use Tamayo\Stretchy\Index\Processor;
use Tamayo\Stretchy\Index\Blueprint;

class IndexGrammarTest extends PHPUnit_Framework_TestCase
{

	public function testBasicCreateIndex()
	{
		$blueprint = new Blueprint('basic');
		$blueprint->create();

		$blueprint->shards(1);
		$blueprint->replicas(3);

		$json = $blueprint->toJson($this->getConnection(), $this->getGrammar());

		$this->assertEquals('{"index":"basic","body":{"settings":{"number_of_shards":1,"number_of_replicas":3}}}', $json);

	}

	public function testBasicCreateIndexWithPrefix()
	{
		$blueprint = new Blueprint('basic');
		$blueprint->create();

		$blueprint->shards(1);
		$blueprint->replicas(3);

		$grammar = $this->getGrammar();
		$grammar->setIndexPrefix('prefix_');

		$json = $blueprint->toJson($this->getConnection(), $grammar);

		$this->assertEquals('{"index":"prefix_basic","body":{"settings":{"number_of_shards":1,"number_of_replicas":3}}}', $json);

	}

	public function testCompileGetSettings()
	{
		$grammar = $this->getGrammar();

		$compiled = $grammar->compileGetSettings(['foo', 'bar']);

		$this->assertEquals($compiled, ['index' => ['foo', 'bar']]);
	}

	public function getGrammar()
	{
		return new Grammar;
	}

	public function getConnection()
	{
		$connection = Mockery::mock('Tamayo\Stretchy\Connection');

		$connection->shouldReceive('getIndexPrefix')->andReturn('');

		return $connection;
	}

	public function getProcessor()
	{
		return new Processor;
	}

	public function getBuilder()
	{
		return new Builder($this->getConnection(), $this->getGrammar(), $this->getProcessor());
	}
}