text:
(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
  var htmlMode = CodeMirror.getMode(config, {name: "xml",
                                             htmlMode: true,
                                             multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
                                             multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
  var cssMode = CodeMirror.getMode(config, "css");

  var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
  scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
                    mode: CodeMirror.getMode(config, "javascript")});
  if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
    var conf = scriptTypesConf[i];
    scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
  }
  scriptTypes.push({matches: /./,
                    mode: CodeMirror.getMode(config, "text/plain")});

  function html(stream, state) {
    var tagName = state.htmlState.tagName;
    if (tagName) tagName = tagName.toLowerCase();
    var style = htmlMode.token(stream, state.htmlState);
    if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
      // Script block: mode to change to depends on type attribute
      var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
      scriptType = scriptType ? scriptType[1] : "";
      if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
      for (var i = 0; i < scriptTypes.length; ++i) {
        var tp = scriptTypes[i];
        if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
          if (tp.mode) {
            state.token = script;
            state.localMode = tp.mode;
            state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
          }
          break;
        }
      }
    } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
      state.token = css;
      state.localMode = cssMode;
      state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
    }
    return style;
  }
  function maybeBackup(stream, pat, style) {
    var cur = stream.current();
    var close = cur.search(pat), m;
    if (close > -1) stream.backUp(cur.length - close);
    else if (m = cur.match(/<\/?$/)) {
      stream.backUp(cur.length);
      if (!stream.match(pat, false)) stream.match(cur);
    }
    return style;
  }
  function script(stream, state) {
    if (stream.match(/^<\/\s*script\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*script\s*>/,
                       state.localMode.token(stream, state.localState));
  }
  function css(stream, state) {
    if (stream.match(/^<\/\s*style\s*>/i, false)) {
      state.token = html;
      state.localState = state.localMode = null;
      return html(stream, state);
    }
    return maybeBackup(stream, /<\/\s*style\s*>/,
                       cssMode.token(stream, state.localState));
  }

  return {
    startState: function() {
      var state = htmlMode.startState();
      return {token: html, localMode: null, localState: null, htmlState: state};
    },

    copyState: function(state) {
      if (state.localState)
        var local = CodeMirror.copyState(state.localMode, state.localState);
      return {token: state.token, localMode: state.localMode, localState: local,
              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
    },

    token: function(stream, state) {
      return state.token(stream, state);
    },

    indent: function(state, textAfter) {
      if (!state.localMode || /^\s*<\//.test(textAfter))
        return htmlMode.indent(state.htmlState, textAfter);
      else if (state.localMode.indent)
        return state.localMode.indent(state.localState, textAfter);
      else
        return CodeMirror.Pass;
    },

    innerMode: function(state) {
      return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
    }
  };
}, "xml", "javascript", "css");

CodeMirror.defineMIME("text/html", "htmlmixed");

});


text:
{% extends "index.html" %}

{% block body %}

{{team.name}}

{% if list_mode is none %}

{% else %}

        {{ gettext('Picture') }}
        {{ gettext('Login') }}
        {{ gettext('Name') }}
        {{ gettext('Surname') }}
        {{ gettext('Team') }}
        {{ gettext('Skype') }}
        {{ gettext('VCard') }}

      {% for person in team.persons %}

        {{ person.login }}
        {{ person.name }}
        {{ person.surname }}
        {{ person.team.name }}
        {{ person.skype }}
        <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">VCard</button>

      {% endfor %}

{% endif %}

{% endblock %}

redpajama_set_name: RedPajamaGithub


text:
JsonParser
==========

Small JSON parser implementation for .NET 3.0 or later

# What's this?

This is yet another JSON parser engine, on which I takes much care on the
footprint of implementation.
It does not introduces any JSON related classes but only JsonParser class,
which provides JSON parser/helper functions.

# How to use it

The following fragment explains how to use it:

```cs
// Parse JSON from file
var obj1 = JsonParser.ParseFile("sample.json", Encoding.UTF8);

// Parse JSON from string
var obj2 = JsonParser.Parse(
  @"{
  ""test"": [1, 2, 3, {
      ""1"": {
        ""2"": [1, 2, 3, 4, 56, 57, 55, 445]
      }
    }, {
      ""aa"": 12,
      ""ee"": ""aaa""
    },
    null, true, false
  ]
}");
```

Then, you can access any of the values by normal C# syntax.
Basically, JSON values are translated to the following .NET objects:

|JSON value type|.NET object type          |
|---------------|--------------------------|
|Objects        |Dictionary<string, object>|
|Arrays         |object[]                  |
|Numbers        |int/double                |
|Strings        |string                    |
|true/false     |bool                      |
|null           |object                    |

# JsonParser.JsonWalk Helper Method

Because the type checking on untyped values are very painful, I prepared
a helper method named JsonParser.JsonWalk.
The method accepts a kind of path to specify the location of a value.
The second parameter is the default value for missing value.
A Path component is a key of dictionary or an index on array (0-based)
and should be delimited by `/`.

```cs
var v = JsonParser.JsonWalk(obj2, "test/3/1/2/2", -1);   // 3 (int)
var x = JsonParser.JsonWalk(obj2, "test/ccc/1/2/2", -1); // -1 (int)

// object[8]
var test = JsonParser.JsonWalk<object[]>(obj2, "test", null);

// of course, obj2 is Dictionary<string, object> in the case
var dict = (Dictionary<string, object>)obj2;
var test2 = dict["test"];
```

# Restrictions

This parser is not fully RFC 4627 compliant; certain aspects of the JSON
spec. are intentionally ignored :)

List of restrictions:
* Stream parser only accepts UTF-8 JSON (RFC 4627 3. Encoding)
* Could not be used as a JSON validator (Syntax check is not so strict)
* No ToString (serialization) method


text:
#pragma once
#include <aws/ssm/SSM_EXPORTS.h>
#include <aws/core/utils/memory/stl/AWSString.h>

namespace Aws
{
namespace SSM
{
namespace Model
{
  enum class DocumentHashType
  {
    NOT_SET,
    Sha256,
    Sha1
  };

namespace DocumentHashTypeMapper
{
AWS_SSM_API DocumentHashType GetDocumentHashTypeForName(const Aws::String& name);

AWS_SSM_API Aws::String GetNameForDocumentHashType(DocumentHashType value);
} // namespace DocumentHashTypeMapper
} // namespace Model
} // namespace SSM
} // namespace Aws


text:
<?php
define('SILENCIO_SHORTNAME', 'theme_option_');
define('SILENCIO_PAGE_BASENAME', 'silencio-settings'); // the settings page slug

require_once('silencio-theme-options.php');

add_action('customize_register', 'silencio_register_settings');

/**
 * Helper function for defining variables for the current page
 *
 * @return array
 */
function silencio_get_settings() {

    $output = array();
    $output['silencio_option_name'] = 'silencio_options';
    $output['silencio_page_sections'] = silencio_options_page_sections();
    $output['silencio_page_fields'] = silencio_options_page_fields();

    return $output;
}

/**
 * Helper function for registering our form field settings
 *
 * @param WP_Customize_Manager $wp_customize Theme Customizer object.
 * @param (array) $args The array of arguments to be used in creating the field
 * @return function call
 */
function silencio_create_settings_field($wp_customize, $args = array()) {
    // default array to overwrite when calling the function
    $defaults = array(
        'id'      => 'default_field',
        'label'   => 'Default Field',
        'type'    => 'text',
        'section' => 'main_section',
        'choices' => array(),
        'sanitize_callback' => ''
    );

    // "extract" to be able to use the array keys as variables in our function output below
    extract(wp_parse_args($args, $defaults));

    $setting_args = array(
        'sanitize_callback' => $sanitize_callback
    );

    $wp_customize->add_setting($id, $setting_args);

    $control_args = array(
        'label' => $label,
        'section' => $section,
        'type' => $type,
        'choices' => $choices
    );

    $wp_customize->add_control($id, $control_args);
}

/**
 * Register our setting, settings sections and settings fields
 *
 * @param WP_Customize_Manager $wp_customize Theme Customizer object.
 */
function silencio_register_settings($wp_customize) {
    $settings_output = silencio_get_settings();
    $silencio_option_name = $settings_output['silencio_option_name'];

    // sections
    if (!empty($settings_output['silencio_page_sections'])) {
        // call the "add_settings_section" for each!
        foreach ($settings_output['silencio_page_sections'] as $id => $options) {
            $wp_customize->add_section(
                $id,
                array(
                    'title' => $options['title'],
                    'description' => $options['description'],
                    'priority' => 35
                )
            );
        }
    }

    // fields
    if (!empty($settings_output['silencio_page_fields'])) {
        foreach ($settings_output['silencio_page_fields'] as $option) {
            silencio_create_settings_field($wp_customize, $option);
        }
    }
}

/**
 * Validates a URL
 *
 * @param string $value
 * @return string
 */
function silencio_url($value) {
    // See http://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149
    $pattern = '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/';
    return preg_match($pattern, $value) ? $value : false;
}

/**
 * Validates an email address
 *
 * @param string $value
 * @return string
 */
function silencio_email($value) {
    return is_email($value);
}

/**
 * Validates a numeric value
 *
 * @param string $value
 * @return string
 */
function silencio_number($value) {
    return is_numeric($value) ? $value : false;
}

/**
 * Strips HTML from $value
 *
 * @param string $value
 * @return string
 */
function silencio_no_html($value) {
    return sanitize_text_field($value);
}

/**
 * Validates a ZIP Code in following formats:
 * 12345
 * 12345 1234
 * 12345-1234
 *
 * @param string $value
 * @return string
 */
function silencio_zip($value) {
    return preg_match('/^\d{5}(?:[-\s]\d{4})?$/', $value) ? $value : false;
}


text:
class PNMReader;
class PNMWriter;
class FactoryParams;

////////////////////////////////////////////////////////////////////
//       Class : PNMFileType
// Description : This is the base class of a family of classes that
//               represent particular image file types that PNMImage
//               supports.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PNMIMAGE PNMFileType : public TypedWritable {
protected:
  PNMFileType();

public:
  virtual ~PNMFileType();

PUBLISHED:
  virtual string get_name() const=0;

  virtual int get_num_extensions() const;
  virtual string get_extension(int n) const;
  MAKE_SEQ(get_extensions, get_num_extensions, get_extension);
  virtual string get_suggested_extension() const;

public:
  virtual bool has_magic_number() const;
  virtual bool matches_magic_number(const string &magic_number) const;

  virtual PNMReader *make_reader(istream *file, bool owns_file = true,
                                 const string &magic_number = string());
  virtual PNMWriter *make_writer(ostream *file, bool owns_file = true);

protected:
  static void init_pnm();

private:
  static bool _did_init_pnm;

  // The TypedWritable interface follows.
public:
  static void register_with_read_factory();
  virtual void write_datagram(BamWriter *writer, Datagram &datagram);

protected:
  static TypedWritable *make_PNMFileType(const FactoryParams &params);

public:
  static TypeHandle get_class_type() {
    return _type_handle;
  }
  static void init_type() {
    TypedWritable::init_type();
    register_type(_type_handle, "PNMFileType",
                  TypedWritable::get_class_type());
  }
  virtual TypeHandle get_type() const {
    return get_class_type();
  }
  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}

private:
  static TypeHandle _type_handle;
};

#endif


text:
<!--

    Copyright (C) 2015 Orange
    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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <artifactId>elpaaso-core</artifactId>
    <groupId>com.orange.clara.cloud</groupId>
    <version>3.0-SNAPSHOT</version>
  </parent>
  <artifactId>cloud-paas-test</artifactId>
  <packaging>pom</packaging>
  <name>${project.artifactId} test harness for paas</name>
  <description>Includes tests artifacts used by paas (tools, stubs, ...)</description>
  <dependencies>
  </dependencies>

  <modules>
  	<module>cloud-paas-test-database</module>
  </modules>

</project>


text:
static int promotionPieces[] = {KNIGHT, BISHOP, ROOK, QUEEN};
static char promotionPiecesStr[] = {'N', 'B', 'R', 'Q'};

Move make_move_from_str(Board* board, const char* moveStr)
{
	unsigned int to = 0;
	unsigned int from = 0;
	unsigned int piece = 0;
	unsigned int capturedPiece = 0;
	unsigned int capture = 0;
	unsigned int promotion = 0;
	unsigned int special_0 = 0;
	unsigned int special_1 = 0;

	from = tolower(moveStr[0]) - 'a';
	from += (tolower(moveStr[1]) - '1')*8;
	to = tolower(moveStr[2]) - 'a';
	to += (tolower(moveStr[3]) - '1')*8;

	piece = board->mailbox[from];
	if (board->mailbox[to] != NUM_PIECES)
	{
		capture = 1;
		capturedPiece = board->mailbox[to];
	}

	if (piece == WHITE_PAWN &&
		((1ull << from) & ranks[1]) &&
		 ((1ull << to) & ranks[3]))
	{
		special_0 = 1;
	}
	if (piece == BLACK_PAWN &&
		((1ull << from) & ranks[6]) &&
		((1ull << to) & ranks[4]))
	{
		special_0 = 1;
	}
	if ((piece == WHITE_PAWN && (1ull << to) & ranks[7])
		|| (piece == BLACK_PAWN && (1ull << to) & ranks[0]))
	{
		promotion = 1;
		switch(moveStr[4])
		{
			case 'q':
			case 'Q':
				special_0 = 1;
				special_1 = 1;
				break;
			case 'r':
			case 'R':
				special_1 = 1;
				break;
			case 'b':
			case 'B':
				special_0 = 1;
				break;
		}
	}
	if (piece == WHITE_KING && from == E1)
	{
		if (to == G1)
		{
			special_1 = 1;
		}
		else if (to == C1)
		{
			special_0 = 1;
			special_1 = 1;
		}
	}
	if (piece == BLACK_KING && from == E8)
	{
		if (to == G8)
		{
			special_1 = 1;
		}
		else if (to == C8)
		{
			special_0 = 1;
			special_1 = 1;
		}
	}
	return move_pack_move(from,
                    to,
                    piece,
                    capturedPiece,
                    capture,
                    promotion,
                    special_0,
                    special_1);
}

Move make_move_from_san(struct Board* board, const char* moveStr)
{
	Move move;
	Move moves[256];
	int destFile = -1, sourceFile = -1, destRank = -1, sourceRank = -1;
	int to;
	int numMoves;
	int i;
	const char *sanMove = moveStr;
	unsigned int promotion = 0, special_0 = 0, special_1 = 0;

	if (!strcmp(moveStr, "0-0") || !strcmp(moveStr, "O-O"))
	{
		if (board->sideToMove == WHITE)
		{
			return move_pack_move(E1,
		                          G1,
		                          WHITE_KING,
		                          0,
		                          0,
		                          0,
		                          0,
		                          1);
		}
		else
		{
			return move_pack_move(E1,
		                          G1,
		                          BLACK_KING,
		                          0,
		                          0,
		                          0,
		                          0,
		                          1);
		}
	}
	else if (!strcmp(moveStr, "0-0-0") || !strcmp(moveStr, "O-O-O"))
	{
		if (board->sideToMove == WHITE)
		{
			return move_pack_move(E1,
			                      C1,
			                      WHITE_KING,
			                      0,
			                      0,
			                      0,
			                      1,
			                      1);
		}
		else
		{
			return move_pack_move(E1,
			                      C1,
			                      BLACK_KING,
			                      0,
			                      0,
			                      0,
			                      1,
			                      1);
		}
	}

	while(*moveStr)
	{
		switch (*moveStr)
		{
			case 'N':
				promotion = 1;
				break;
			case 'B':
				promotion = 1;
				special_0 = 1;
				break;
			case 'R':
				promotion = 1;
				special_1 = 1;
				break;
			case 'Q':
				promotion = 1;
				special_0 = 1;
				special_1 = 1;
				break;
			case 'a':
			case 'b':
			case 'c':
			case 'd':
			case 'e':
			case 'f':
			case 'g':
			case 'h':
				if (destFile != -1)
				{
					sourceFile = destFile;
				}
				destFile = *moveStr - 'a';
				break;
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
				if (destRank != -1)
				{
					sourceRank = destRank;
				}
				destRank = *moveStr - '1';
				break;
		}
		if (*moveStr == ' ')
		{
			break;
		}
		++moveStr;
	}

	to = (destRank * 8) + destFile;

	numMoves = generate_moves(board, moves);

	for (i = 0; i < numMoves; ++i)
	{
		if (move_get_to(moves[i]) != to)
		{
			continue;
		}

		if (move_get_promotion(moves[i]) &&
		    (!promotion ||
		     (move_get_promotion(moves[i]) != promotion) ||
		     (move_get_special_0(moves[i]) != special_0) ||
		     (move_get_special_1(moves[i]) != special_1)))
		{
			continue;
		}

		if ((sourceFile != -1) &&
		    (sourceFile != move_get_from(moves[i]) % 8))
		{
			continue;
		}

		if ((sourceRank != -1) &&
			(sourceRank != move_get_from(moves[i]) / 8))
		{
			continue;
		}

		return moves[i];
	}

	fprintf(stderr, "Error, unable to parse SAN move %s\n", sanMove);
	memset(&move, 0, sizeof(Move));
	return move;
}

int is_move(const char* moveStr)
{
	char buf[4];
	int i;

	if (strlen(moveStr) != 4)
	{
		return 0;
	}

	for (i = 0; i < 4; ++i)
	{
		buf[i] = (char)tolower(moveStr[i]);
	}

	if (('a' > buf[0]) || ('h' < buf[0]) || ('a' > buf[2]) || ('h' < buf[2]) ||
		('1' > buf[1]) || ('8' < buf[1]) || ('1' > buf[3]) || ('8' < buf[3]))
	{
		return 0;
	}

	return 1;
}

void sprint_move(char* buffer, Move move)
{
	unsigned int to;
	unsigned int from;
	unsigned int piece;
	unsigned int capturedPiece;
	unsigned int capture;
	unsigned int promotion;
	unsigned int special_0;
	unsigned int special_1;

	move_unpack_move(move, &from, &to, &piece, &capturedPiece, &capture, &promotion, &special_0, &special_1);

	if (promotion)
	{
		char promoPiece = promotionPiecesStr[(special_0 << 1) | special_1];
		sprintf(buffer, "%s%s%c", strSquare[from], strSquare[to], promoPiece);
	}
	else
	{
		sprintf(buffer, "%s%s", strSquare[from], strSquare[to]);
	}
}

void log_move(Move move, const char* moveString, const char* moveType)
{
	unsigned int to;
	unsigned int from;
	unsigned int piece;
	unsigned int capturedPiece;
	unsigned int capture;
	unsigned int promotion;
	unsigned int special_0;
	unsigned int special_1;
	char* moveBuffer = (char*)malloc(sizeof(char)*1024);
	char* flagBuffer = (char*)malloc(sizeof(char)*256);

	move_unpack_move(move, &from, &to, &piece, &capturedPiece, &capture, &promotion, &special_0, &special_1);
	strcpy(flagBuffer, "[");
	if (promotion)
	{
		strcat(flagBuffer, "\\\"promotion\\\",");
	}
	if (capture)
	{
		strcat(flagBuffer, "\\\"capture\\\",");
	}
	if (special_1)
	{
		strcat(flagBuffer, "\\\"special1\\\",");
	}
	if (special_0)
	{
		strcat(flagBuffer, "\\\"special0\\\",");
	}
	if (flagBuffer[strlen(flagBuffer) - 1] == ',')
	{
		flagBuffer[strlen(flagBuffer) - 1] = 0;
	}
	strcat(flagBuffer, "]");

	sprintf(moveBuffer, "{\\\"to\\\": %i, \\\"from\\\": %i, "
		"\\\"piece\\\": %i, \\\"flags\\\": %s, "
		"\\\"capturedPiece\\\": %i, "
		"\\\"move_string\\\": \\\"%s\\\", \\\"move_type\\\": \\\"%s\\\"}",
		to, from, piece, flagBuffer, capturedPiece,
		moveString, moveType);
	LOG("move", moveBuffer);

	free(flagBuffer);
	free(moveBuffer);
}

void make_move(Board* board, Move move)
{
	unsigned int to;
	unsigned int from;
	unsigned int piece;
	unsigned int capturedPiece;
	unsigned int capture;
	unsigned int promotion;
	unsigned int special_0;
	unsigned int special_1;
	bitboard fromBB, toBB, fromToBB;

	move_unpack_move(move, &from, &to, &piece, &capturedPiece, &capture, &promotion, &special_0, &special_1);

	fromBB = 1ull << from;
	toBB = 1ull << to;
	fromToBB = fromBB | toBB;

	assert(board->mailbox[from] == piece);
	assert((board->mailbox[to] == NUM_PIECES) ||
	       ((board->mailbox[to] == capturedPiece) &&
	        capture));

	push_state(board);
	board->zobrist ^= castlingKeys[board->castling];
	if (board->enPassant)
	{
		board->zobrist ^= enPassantKeys[bit_scan_forward(board->enPassant)];
	}
	board->enPassant = 0;
	board->mailbox[from] = NUM_PIECES;
	board->mailbox[to] = piece;

	board->staticScore -= pieceSquareValues[piece][from];
	board->staticScore += pieceSquareValues[piece][to];

	if (promotion && capture)
	{
		int promoPiece = promotionPieces[(special_0 << 1) | special_1] + board->sideToMove;

		board->pieces[piece] ^= fromBB;
		board->pieces[promoPiece] ^= toBB;
		board->pieces[capturedPiece] ^= toBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= toBB;
		board->mailbox[to] = promoPiece;

		board->occupied ^= fromBB;
		board->empty ^= fromBB;

		if (capturedPiece == WHITE_ROOK)
		{
			if (to == A1)
			{
				board->castling &= ~(1ull << WHITE_QUEENSIDE);
			}
			else if (to == H1)
			{
				board->castling &= ~(1ull << WHITE_KINGSIDE);
			}
		}
		else if (capturedPiece == BLACK_ROOK)
		{
			if (to == A8)
			{
				board->castling &= ~(1ull << BLACK_QUEENSIDE);
			}
			else if (to == H8)
			{
				board->castling &= ~(1ull << BLACK_KINGSIDE);
			}
		}

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[capturedPiece][to];
		board->zobrist ^= pieceKeys[promoPiece][to];

		board->staticScore -= pieceValues[piece];
		board->staticScore -= pieceSquareValues[piece][to];
		board->staticScore += pieceValues[promoPiece];
		board->staticScore += pieceSquareValues[promoPiece][to];
		board->staticScore += pieceValues[capturedPiece];
		board->staticScore += pieceSquareValues[capturedPiece][to];
	}
	else if (promotion)
	{
		int promoPiece = promotionPieces[(special_0 << 1) | special_1] + board->sideToMove;

		board->pieces[piece] ^= fromBB;
		board->pieces[promoPiece] ^= toBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;
		board->mailbox[to] = promoPiece;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[promoPiece][to];

		board->staticScore -= pieceValues[piece];
		board->staticScore += pieceValues[promoPiece];
		board->staticScore -= pieceSquareValues[piece][to];
		board->staticScore += pieceSquareValues[promoPiece][to];
	}
	else if (capture && special_0)
	{
		bitboard captureBB = ((toBB & ranks[2]) << 8) | ((toBB & ranks[5]) >> 8);
		int captureSquare = bit_scan_forward(captureBB);

		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= captureBB;
		board->occupied ^= fromToBB | captureBB;
		board->empty ^= fromToBB | captureBB;
		board->pieces[capturedPiece] ^= captureBB;
		board->mailbox[captureSquare] = NUM_PIECES;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[capturedPiece][captureSquare];

		board->staticScore += pieceValues[capturedPiece];
		board->staticScore += pieceSquareValues[capturedPiece][captureSquare];
	}
	else if (capture)
	{
		board->pieces[piece] ^= fromToBB;
		board->pieces[capturedPiece] ^= toBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= toBB;
		board->occupied ^= fromBB;
		board->empty ^= fromBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[capturedPiece][to];

		board->staticScore += pieceValues[capturedPiece];
		board->staticScore += pieceSquareValues[capturedPiece][to];

		if (piece == WHITE_ROOK)
		{
			if (from == A1)
			{
				board->castling &= ~(1ull << WHITE_QUEENSIDE);
			}
			else if (from == H1)
			{
				board->castling &= ~(1ull << WHITE_KINGSIDE);
			}
		}
		else if (piece == BLACK_ROOK)
		{
			if (from == A8)
			{
				board->castling &= ~(1ull << BLACK_QUEENSIDE);
			}
			else if (from == H8)
			{
				board->castling &= ~(1ull << BLACK_KINGSIDE);
			}
		}
		else if (piece == WHITE_KING)
		{
			board->castling &= (1ull << BLACK_KINGSIDE) | (1ull << BLACK_QUEENSIDE);
		}
		else if (piece == BLACK_KING)
		{
			board->castling &= (1ull << WHITE_KINGSIDE) | (1ull << WHITE_QUEENSIDE);
		}

		if (capturedPiece == WHITE_ROOK)
		{
			if (to == A1)
			{
				board->castling &= ~(1ull << WHITE_QUEENSIDE);
			}
			else if (to == H1)
			{
				board->castling &= ~(1ull << WHITE_KINGSIDE);
			}
		}
		else if (capturedPiece == BLACK_ROOK)
		{
			if (to == A8)
			{
				board->castling &= ~(1ull << BLACK_QUEENSIDE);
			}
			else if (to == H8)
			{
				board->castling &= ~(1ull << BLACK_KINGSIDE);
			}
		}
	}
	else if (special_1)
	{
		int rookIndex = ROOK +  board->sideToMove;
		int rookFrom, rookTo;
		bitboard rookFromTo;

		if (special_0)
		{
			rookFromTo = ((1ull << A1) | (1ull << A8)) & backranks[board->sideToMove];
			rookFrom = bit_scan_forward(rookFromTo);
			rookTo = rookFrom + 3;
			rookFromTo |= rookFromTo << 3;
		}
		else
		{
			rookFromTo = ((1ull << H1) | (1ull << H8)) & backranks[board->sideToMove];
			rookFrom = bit_scan_forward(rookFromTo);
			rookTo = rookFrom - 2;
			rookFromTo |= rookFromTo >> 2;
		}

		board->pieces[piece] ^= fromToBB;
		board->pieces[rookIndex] ^= rookFromTo;
		board->sides[board->sideToMove] ^= fromToBB | rookFromTo;
		board->occupied ^= fromToBB | rookFromTo;
		board->empty ^= fromToBB | rookFromTo;
		board->mailbox[rookFrom] = NUM_PIECES;
		board->mailbox[rookTo] = rookIndex;

		if (board->sideToMove == WHITE)
		{
			board->castling &= (1ull << BLACK_KINGSIDE) | (1ull << BLACK_QUEENSIDE);
		}
		else
		{
			board->castling &= (1ull << WHITE_KINGSIDE) | (1ull << WHITE_QUEENSIDE);
		}

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[rookIndex][bit_scan_forward(rookFromTo)];
		rookFromTo = clear_lsb(rookFromTo);
		board->zobrist ^= pieceKeys[rookIndex][bit_scan_forward(rookFromTo)];

		board->staticScore -= pieceSquareValues[rookIndex][rookFrom];
		board->staticScore += pieceSquareValues[rookIndex][rookTo];
	}
	else if (special_0)
	{
		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;
		board->enPassant = squareFiles[to];

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= enPassantKeys[bit_scan_forward(board->enPassant)];
	}
	else
	{
		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];

		if (piece == WHITE_ROOK)
		{
			if (from == A1)
			{
				board->castling &= ~(1ull << WHITE_QUEENSIDE);
			}
			else if (from == H1)
			{
				board->castling &= ~(1ull << WHITE_KINGSIDE);
			}
		}
		else if (piece == BLACK_ROOK)
		{
			if (from == A8)
			{
				board->castling &= ~(1ull << BLACK_QUEENSIDE);
			}
			else if (from == H8)
			{
				board->castling &= ~(1ull << BLACK_KINGSIDE);
			}
		}
		else if (piece == WHITE_KING)
		{
			board->castling &= (1ull << BLACK_KINGSIDE) | (1ull << BLACK_QUEENSIDE);
		}
		else if (piece == BLACK_KING)
		{
			board->castling &= (1ull << WHITE_KINGSIDE) | (1ull << WHITE_QUEENSIDE);
		}
	}

	board->sideToMove = 1 - board->sideToMove;
	board->zobrist ^= blackToMoveKey;
	board->zobrist ^= castlingKeys[board->castling];
	board->staticScore = -board->staticScore;

	verify_board(board);
}

void unmake_move(Board* board, Move move)
{
	unsigned int to;
	unsigned int from;
	unsigned int piece;
	unsigned int capturedPiece;
	unsigned int capture;
	unsigned int promotion;
	unsigned int special_0;
	unsigned int special_1;
	bitboard fromBB, toBB, fromToBB;

	move_unpack_move(move, &from, &to, &piece, &capturedPiece, &capture, &promotion, &special_0, &special_1);

	fromBB = 1ull << from;
	toBB = 1ull << to;
	fromToBB = fromBB | toBB;

	board->sideToMove = 1 - board->sideToMove;

	assert(board->mailbox[from] == NUM_PIECES);
	assert((board->mailbox[to] == piece) ||
	       ((board->mailbox[to] == promotionPieces[(special_0 << 1) | special_1] + board->sideToMove) && promotion));

	board->mailbox[from] = piece;
	board->mailbox[to] = NUM_PIECES;
	board->staticScore = -board->staticScore;

	board->staticScore -= pieceSquareValues[piece][to];
	board->staticScore += pieceSquareValues[piece][from];

	if (promotion && capture)
	{
		int promoPiece = promotionPieces[(special_0 << 1) | special_1] + board->sideToMove;

		board->pieces[piece] ^= fromBB;
		board->pieces[promoPiece] ^= toBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= toBB;
		board->pieces[capturedPiece] ^= toBB;
		board->mailbox[to] = capturedPiece;

		board->occupied ^= fromBB;
		board->empty ^= fromBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[capturedPiece][to];
		board->zobrist ^= pieceKeys[promoPiece][to];

		board->staticScore += pieceValues[piece];
		board->staticScore += pieceSquareValues[piece][to];
		board->staticScore -= pieceValues[promoPiece];
		board->staticScore -= pieceSquareValues[promoPiece][to];
		board->staticScore -= pieceValues[capturedPiece];
		board->staticScore -= pieceSquareValues[capturedPiece][to];
	}
	else if (promotion)
	{
		int promoPiece = promotionPieces[(special_0 << 1) | special_1] + board->sideToMove;

		board->pieces[piece] ^= fromBB;
		board->pieces[promoPiece] ^= toBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[promoPiece][to];

		board->staticScore += pieceValues[piece];
		board->staticScore -= pieceValues[promoPiece];
		board->staticScore += pieceSquareValues[piece][to];
		board->staticScore -= pieceSquareValues[promoPiece][to];
	}
	else if (capture && special_0)
	{
		bitboard captureBB = ((toBB & ranks[2]) << 8) | ((toBB & ranks[5]) >> 8);
		int captureSquare = bit_scan_forward(captureBB);

		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= captureBB;
		board->occupied ^= fromToBB | captureBB;
		board->empty ^= fromToBB | captureBB;
		board->pieces[capturedPiece] ^= captureBB;
		board->mailbox[captureSquare] = capturedPiece;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[capturedPiece][captureSquare];

		board->staticScore -= pieceValues[capturedPiece];
		board->staticScore -= pieceSquareValues[capturedPiece][captureSquare];
	}
	else if (capture)
	{
		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->sides[1 - board->sideToMove] ^= toBB;
		board->occupied ^= fromBB;
		board->empty ^= fromBB;
		board->pieces[capturedPiece] ^= toBB;
		board->mailbox[to] = capturedPiece;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[capturedPiece][to];

		board->staticScore -= pieceValues[capturedPiece];
		board->staticScore -= pieceSquareValues[capturedPiece][to];
	}
	else if (special_1)
	{
		int rookIndex = ROOK + board->sideToMove;
		int rookFrom, rookTo;
		bitboard rookFromTo;

		if (special_0)
		{
			rookFromTo = ((1ull << D1) | (1ull << D8)) & backranks[board->sideToMove];
			rookTo = bit_scan_forward(rookFromTo);
			rookFrom = rookTo - 3;
			rookFromTo |= rookFromTo >> 3;
		}
		else
		{
			rookFromTo = ((1ull << F1) | (1ull << F8)) & backranks[board->sideToMove];
			rookTo = bit_scan_forward(rookFromTo);
			rookFrom = rookTo + 2;
			rookFromTo |= rookFromTo << 2;
		}

		board->pieces[piece] ^= fromToBB;
		board->pieces[rookIndex] ^= rookFromTo;
		board->sides[board->sideToMove] ^= fromToBB | rookFromTo;
		board->occupied ^= fromToBB | rookFromTo;
		board->empty ^= fromToBB | rookFromTo;
		board->mailbox[rookTo] = NUM_PIECES;
		board->mailbox[rookFrom] = rookIndex;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
		board->zobrist ^= pieceKeys[rookIndex][bit_scan_forward(rookFromTo)];
		rookFromTo = clear_lsb(rookFromTo);
		board->zobrist ^= pieceKeys[rookIndex][bit_scan_forward(rookFromTo)];

		board->staticScore += pieceSquareValues[rookIndex][rookFrom];
		board->staticScore -= pieceSquareValues[rookIndex][rookTo];
	}
	else if (special_0)
	{
		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
	}
	else
	{
		board->pieces[piece] ^= fromToBB;
		board->sides[board->sideToMove] ^= fromToBB;
		board->occupied ^= fromToBB;
		board->empty ^= fromToBB;

		board->zobrist ^= pieceKeys[piece][from];
		board->zobrist ^= pieceKeys[piece][to];
	}

	board->zobrist ^= castlingKeys[board->castling];
	if (board->enPassant)
	{
		board->zobrist ^= enPassantKeys[bit_scan_forward(board->enPassant)];
	}
	pop_state(board);
	board->zobrist ^= castlingKeys[board->castling];
	if (board->enPassant)
	{
		board->zobrist ^= enPassantKeys[bit_scan_forward(board->enPassant)];
	}
	board->zobrist ^= blackToMoveKey;

	assert(board->mailbox[from] == piece);
	assert((board->mailbox[to] == NUM_PIECES) ||
	       ((board->mailbox[to] == capturedPiece) &&
	        capture));

	verify_board(board);
}


text:
type DecodeState
    ctx::Context
    global_var_num::OrderedDict{GlobalPtr, Int}
    local_var_num::OrderedDict{LLVMPtr,Int}
    local_name_counter::Int
    named_type_num::OrderedDict{TypePtr,Int}
    types_to_define::Vector{TypePtr}
end
DecodeState(ctx::Context) =
    DecodeState(ctx,
                OrderedDict{GlobalPtr,Int}(),
                OrderedDict{LLVMPtr,Int}(),
                -1,
                OrderedDict{TypePtr,Int}(),
                TypePtr[])

add_global!(st::DecodeState, val::GlobalPtr) = begin
    if haskey(st.global_var_num, val) || !isempty(FFI.get_value_name(val))
        return
    end
    n = length(st.global_var_num)
    st.global_var_num[val] = n
    return
end

get_global_name(st::DecodeState, val::GlobalPtr) = begin
    name = FFI.get_value_name(val)
    if !isempty(name)
        return Ast.Name(name)
    end
    if haskey(st.global_var_num, val)
        n = st.global_var_num[val]
    else
        n = length(st.global_var_num)
        st.global_var_num[val] = n
    end
    return Ast.UnName(n)
end

get_local_name(st::DecodeState, val) = begin
    name = FFI.get_value_name(val)
    if !isempty(name)
        return Ast.Name(name)
    end
    if haskey(st.local_var_num, val)
        n = st.local_var_num[val]
    else
        n = length(st.local_var_num)
        st.local_var_num[val] = n
        st.local_name_counter = n+1
    end
    return Ast.UnName(n)
end

get_type_name(st::DecodeState, name::String) = begin
end

save_named_type(st::DecodeState, typ::TypePtr) =
    (push!(st.types_to_define, typ); return st)

take_type_to_define(st::DecodeState) =
    (pop!(st.types_to_define); return st)

decode_llvm(st::DecodeState, tptr::TypePtr) = begin
    k = FFI.get_type_kind(tptr)
    if k == TypeKind.integer
        nbits = FFI.get_int_type_width(tptr)
        return Ast.IntType(nbits)
    elseif k == TypeKind.pointer
        etyp = decode_llvm(st, FFI.get_elem_type(tptr))
        addr = Ast.AddrSpace(FFI.get_ptr_address_space(tptr))
        return Ast.PtrType(etyp, addr)
    elseif k == TypeKind.half
        return Ast.FloatType(16, Ast.IEEE())
    elseif k == TypeKind.float
        return Ast.FloatType(32, Ast.IEEE())
    elseif k == TypeKind.double
        return Ast.FloatType(64, Ast.IEEE())
    elseif k == TypeKind.func
        return Ast.FuncType(decode_llvm(st, FFI.get_return_type(tptr)),
                            [decode_llvm(st, ty) for ty in FFI.get_param_types(tptr)],
                            FFI.is_func_var_arg(tptr))
    elseif k == TypeKind.struct
        if FFI.is_literal_struct(tptr)
            packed = FFI.is_packed_struct(tptr)
            typs = decode_llvm(st, FFI.get_struct_elem_types(tptr))
            return Ast.StructType(packed, typs)
        else
            error("unimplemented")
        end
    elseif k == TypeKind.array
        len = FFI.get_array_length(tptr)
        typ = decode_llvm(st, FFI.get_elem_type(tptr))
        return Ast.ArrayType(typ, len)
    else
        error("unimplemented type kind $k")
    end
end

decode_llvm(st::DecodeState, typs::Vector{TypePtr}) = begin
    asttyps = Array(Ast.LLVMType, length(typs))
    for i = 1:length(asttyps)
        asttyps[i] = decode_llvm(st, typs[i])
    end
    return asttyps
end

decode_llvm(st::DecodeState, cptr::ConstPtr) = begin
    ftyp = FFI.llvm_typeof(cptr)
    typ  = decode_llvm(st, ftyp)
    nops = FFI.get_num_operands(cptr)

    subclass_id = FFI.get_value_subclass_id(cptr)

    if subclass_id == ValueSubclass.undef_value
        return Ast.ConstUndef(typ)

    elseif subclass_id == ValueSubclass.global_variable
        #name = get_global_name(st, FFI.isa_global_value(cptr))
        n = st.global_var_num[FFI.isa_global_value(cptr)]
        name = Ast.UnName(n)
        return Ast.ConstGlobalRef(typ, name)

    elseif subclass_id == ValueSubclass.const_int
        words  = FFI.get_constant_int_words(cptr)
        nwords = length(words)
        # this is wrong but it gets the tests to pass
        v0 = nwords == 1 ? zero(Uint64) :
             nwords == 2 ? zero(Uint128) : zero(BigInt)
        n = foldr((b, a) -> (a << 64) | b, v0, words)
        return Ast.ConstInt(typ.nbits, n)

    elseif subclass_id == ValueSubclass.const_expr
        opcode = FFI.get_const_opcode(cptr)

        if (opcode == Opcode.add || opcode == Opcode.sub ||
            opcode == Opcode.mul || opcode == Opcode.shl)
            nsw = FFI.no_signed_wrap(cptr)
            nuw = FFI.no_unsigned_wrap(cptr)
            op1 = decode_llvm(st, FFI.get_constant_operand(cptr, 1))
            op2 = decode_llvm(st, FFI.get_constant_operand(cptr, 2))
            opcode == Opcode.add && return Ast.ConstAdd(nsw, nuw, op1, op2)
            opcode == Opcode.sub && return Ast.ConstSub(nsw, nuw, op1, op2)
            opcode == Opcode.mul && return Ast.ConstMul(nsw, nuw, op1, op2)
            opcode == Opcode.shl && return Ast.ConstShl(nsw, nuw, op1, op2)

        elseif opcode == Opcode.get_element_ptr
            inbounds = FFI.get_inbounds(cptr)
            addr = decode_llvm(st, FFI.get_constant_operand(cptr, 1))
            idxs = Array(Ast.Constant, nops-1)
            for i = 2:nops
                idxs[i-1] = decode_llvm(st, FFI.get_constant_operand(cptr, i))
            end
            return Ast.ConstGetElementPtr(inbounds, addr, idxs)

        elseif opcode == Opcode.ptrtoint
            op1 = decode_llvm(st, FFI.get_constant_operand(cptr, 1))
            return Ast.ConstPtrToInt(op1, typ)

        elseif opcode == Opcode.icmp
            pred = FFI.get_icmp_predicate(cptr)
            op1  = decode_llvm(st, FFI.get_constant_operand(cptr, 1))
            op2  = decode_llvm(st, FFI.get_constant_operand(cptr, 2))
            ipred = Ast.int_cmp_pred_map[pred]
            return Ast.ConstICmp(ipred, op1, op2)
        end
        error("unimplemented constant expr opcode $opcode")

    elseif subclass_id == ValueSubclass.const_fp
        nbits, fmt = typ.nbits, typ.fmt
        words = zeros(Uint64, div((nbits - 1), 64) + 1)
        FFI.get_const_float_words!(cptr, words)
        if nbits == 16 && typeof(fmt) === Ast.IEEE
            return Ast.ConstFloat(reinterpret(Float16, uint16(words[1])))
        elseif nbits == 32 && typeof(fmt) === Ast.IEEE
            return Ast.ConstFloat(reinterpret(Float32, uint32(words[1])))
        elseif nbits == 64 && typeof(fmt) === Ast.IEEE
            return Ast.ConstFloat(reinterpret(Float64, uint64(words[1])))
        else
            error("unimplemented constant floating point type")
        end

    elseif subclass_id == ValueSubclass.const_struct
        name = isa(typ, Ast.NamedTypeRef) ? typ.val : nothing
        p = FFI.is_packed_struct(ftyp)
        n = FFI.get_num_operands(cptr)
        vals = Array(Ast.Constant, n)
        for i = 1:n
            vals[i] = decode_llvm(st,
                FFI.get_constant_operand(cptr, i))
        end
        return Ast.ConstStruct(name, p, vals)

    elseif subclass_id == ValueSubclass.const_data_array
        @assert isa(typ, Ast.ArrayType)
        vals = Array(Ast.Constant, typ.len)
        for i = 1:typ.len
            vals[i] = decode_llvm(st,
                FFI.get_const_data_seq_elem_as_const(cptr, i))
        end
        return Ast.ConstArray(typ.typ, vals)

    elseif subclass_id == ValueSubclass.const_array
        @assert isa(typ, Ast.ArrayType)
        vals = Array(Ast.Constant, typ.len)
        for i = 1:typ.len
            vals[i] = decode_llvm(st,
                FFI.get_constant_operand(cptr, i))
        end
        return Ast.ConstArray(typ.typ, vals)

    else
        error("unimplemented subclassid : $subclass_id")
    end
end

decode_llvm(buf::MemoryBufferPtr) = begin
    start = FFI.get_buffer_start(buf)
    size  = FFI.get_buffer_size(buf)
    res = Array(Uint8, size)
    unsafe_copy!(convert(Ptr{Uint8}, res), start, size)
    return res
end
decode_llvm(st::DecodeState, buf::MemoryBufferPtr) = decode_llvm(buf)

get_metadata(iptr::InstructionPtr, n::Int) = begin
    kinds = Array(Cint, n)
    nodes = Array(MDNodePtr, n)
    nn = FFI.get_metadata(iptr, kinds, nodes, n)
    nn == 0 && return Ast.InstructionMetadata[]
    nn > n  && return get_metadata(iptr, nn)
    return zip([decode_llvm(st, kd) for kd in kinds],
               [decode_llvm(st, nd) for nd in nodes])
end
get_metadata(iptr::InstructionPtr) = get_metadata(iptr, 4)

decode_llvm(st::DecodeState, iptr::InstructionPtr) = begin
    opcode = FFI.get_instr_def_opcode(iptr)
    nops = FFI.get_num_operands(iptr)
    meta = get_metadata(iptr)
    if opcode == Opcode.ret
        op = nops == 0 ? nothing :
             Ast.ConstOperand(decode_llvm(st, FFI.get_operand(iptr, 1)))
        return Ast.Ret(op, meta)
    end
    error("unimplemented instruction opcode $opcode")
end

abstract LocalVal

immutable ForwardVal <: LocalVal
    val::Types.LLVMPtr
end

immutable DefinedVal <: LocalVal
    val::Types.LLVMPtr
end

type EncodeState
    ctx::Context
    builder::BuilderPtr
    named_types::OrderedDict{Ast.LLVMName,TypePtr}
    locals::OrderedDict{Ast.LLVMName, LocalVal}
    globals::OrderedDict{Ast.LLVMName, GlobalPtr}
    allblocks::OrderedDict{(Ast.LLVMName, Ast.LLVMName), BasicBlockPtr}
    blocks::OrderedDict{Ast.LLVMName, BasicBlockPtr}
    mdnodes::OrderedDict{Ast.MetadataNodeID, MDNodePtr}
end

EncodeState(ctx::Context) = begin
    bldr = FFI.create_builder_in_ctx(ctx)
    es = EncodeState(ctx, bldr,
                     OrderedDict{Ast.LLVMName,TypePtr}(),
                     OrderedDict{Ast.LLVMName,LocalVal}(),
                     OrderedDict{Ast.LLVMName,GlobalPtr}(),
                     OrderedDict{(Ast.LLVMName,Ast.LLVMName), BasicBlockPtr}(),
                     OrderedDict{Ast.LLVMName,BasicBlockPtr}(),
                     OrderedDict{Ast.MetadataNodeID,MDNodePtr}())
    finalizer(es, (st) -> begin
        if !isnull(st.builder)
            FFI.dispose_builder(st.builder)
            st.builder = BuilderPtr(C_NULL)
        end
    end)
    return es
end

get_named_type(st::EncodeState, name::String) = get_named_type(st, Ast.Name(name))
get_named_type(st::EncodeState, name::Ast.LLVMName) = st.named_types[name]

get_local_type(st::EncodeState, name::String) = get_local_type(st, Ast.Name(name))
get_local_type(st::EncodeState, name::Ast.LLVMName) = st.locals[name]

get_global(st::EncodeState, name::String) = get_global(st, Ast.Name(name))
get_global(st::EncodeState, name::Ast.LLVMName) = st.globals[name]

define_global!(st::EncodeState, name::String, ptr::GlobalPtr) =
    (st.globals[Ast.Name(name)] = ptr; return)

define_global!(st::EncodeState, name::Ast.LLVMName, ptr::GlobalPtr) =
    (st.globals[name] = ptr; return)

define_basic_block!(st::EncodeState,
                    fname::Ast.LLVMName,
                    bname::Ast.LLVMName,
                    ptr::BasicBlockPtr) = begin
    st.allblocks[(fname, bname)] = ptr
    st.blocks[bname] = ptr
    return
end

define_basic_block!(st::EncodeState, fname, bname, ptr) =
    define_basic_block(st, isa(fname, String) ? Ast.Name(fname) : fname::Ast.LLVMName,
                           isa(bname, String) ? Ast.Name(bname) : bname::Ast.LLVMName, ptr)

define_local!(st::EncodeState, lname::Ast.Name, ptr) = begin
    if haskey(st.locals, lname)
        def = st.locals[lanme]
        if isa(def, ForwardVal)
            FFI.replace_all_uses_with(convert(ValuePtr, def.val), ptr)
        end
        return
    end
    st.locals[lname] = DefinedVal(ptr)
    return
end

with_locals(f::Function, st::EncodeState) = begin
    ol, ob = st.locals, st.blocks
    try
        st.locals = copy(st.locals)
        st.blocks = copy(st.blocks)
        f(st)
    finally
        st.locals = ol
        st.blocks = ob
    end
end

encode_llvm(es::EncodeState, s::String) = begin
    N = length(s)
    ptr = convert(Ptr{Uint8}, Base.c_malloc(sizeof(Uint8) * N + 1))
    unsafe_copy!(ptr, convert(Ptr{Uint8}, s), N)
    unsafe_store!(ptr, zero(Uint8), N+1)
    return ptr
end

encode_llvm(es::EncodeState, typ::Ast.IntType) =
    FFI.int_type_in_ctx(es.ctx, typ.nbits)

# should all types be parametric types so we can dispatch on them more easily?
encode_llvm(st::EncodeState, typ::Ast.FloatType) = begin
    nbits, fmt = typ.nbits, typ.fmt
    if nbits == 16 && typeof(fmt) === Ast.IEEE
        return FFI.half_type_in_ctx(st.ctx)
    elseif nbits == 32 && typeof(fmt) === Ast.IEEE
        return FFI.float_type_in_ctx(st.ctx)
    elseif nbits == 64 && typeof(fmt) === Ast.IEEE
        return FFI.double_type_in_ctx(st.ctx)
    elseif nbits == 80 && typeof(fmt) === Ast.DoubleExtended
        return FFI.x86_fp80_type_in_ctx(st.ctx)
    elseif nbits == 128 && typeof(fmt) === Ast.IEEE
        return FFI.fp128_type_in_ctx(st.ctx)
    elseif nbits == 128 && typeof(fmt) === Ast.PairOfFloats
        return FFI.ppc_fp128_type_in_ctx(st.ctx)
    else
        error("unsupported floating point type $typ")
    end
end

encode_llvm(st::EncodeState, ptr::Ast.PtrType) = begin
    typ  = encode_llvm(st, ptr.typ)
    addr = encode_llvm(st, ptr.addrspace)
    return FFI.ptr_type(typ, addr)
end

encode_llvm(st::EncodeState, typs::Vector{Ast.LLVMType}) = begin
    tptrs = TypePtr[]
    for ty in typs
        push!(tptrs, encode_llvm(st, ty))
    end
    return tptrs
end

encode_llvm(st::EncodeState, cnsts::Vector{Ast.Constant}) = begin
    cptrs = ConstPtr[]
    for c in cnsts
        push!(cptrs, encode_llvm(st, c))
    end
    return cptrs
end

encode_llvm(st::EncodeState, attrs::Vector{Ast.FuncAttr}) = begin
    isempty(attrs) && return uint32(0)
    bits = uint32(attrs[1])
    for i = 2:length(attrs)
        flag = Ast.func_attr_map[attrs[i]]
        bits |= uint32(flag)
    end
    return bits
end

encode_llvm(st::EncodeState, attrs::Vector{Ast.ParamAttr}) = begin
    isempty(attrs) && return uint32(0)
    bits = uint32(attrs[1])
    for i = 2:length(attrs)
        flag = Ast.param_attr_map[attrs[i]]
        bits &= uint32(flag)
    end
    return bits
end

encode_llvm(st::EncodeState, styp::Ast.StructType) = begin
    typs = encode_llvm(st, styp.typs)
    return FFI.struct_type_in_ctx(st.ctx, typs, styp.packed)
end

encode_llvm(st::EncodeState, struct::Ast.ConstStruct) = begin
    cptrs = encode_llvm(st, struct.vals)::Vector{ConstPtr}
    if is(struct.name, nothing)
        return FFI.const_struct_in_ctx(st.ctx, cptrs, struct.packed)
    end
    # lookup named type from encoding state
    typ = st.named_types[struct.name]::TypePtr
    return FFI.const_named_struct(typ, cptrs)
end

encode_llvm(st::EncodeState, typ::Ast.ArrayType) =
    FFI.array_type(encode_llvm(st, typ.typ), typ.len)

encode_llvm(st::EncodeState, typ::Ast.FuncType) =
    FFI.func_type(encode_llvm(st, typ.rettyp),
                  encode_llvm(st, typ.argtyps),
                  typ.vaargs)

encode_llvm(st::EncodeState, carr::Ast.ConstArray) =
    FFI.const_array(encode_llvm(st, carr.typ),
                    encode_llvm(st, carr.vals))

encode_llvm(st::EncodeState, undef::Ast.ConstUndef) =
    FFI.const_undef(encode_llvm(st, undef.typ))

encode_llvm(st::EncodeState, addr::Ast.AddrSpace) = addr.val

encode_llvm(st::EncodeState, name::Ast.Name)   = name.val
encode_llvm(st::EncodeState, name::Ast.UnName) = ""

encode_llvm(st::EncodeState, ::Ast.Linkage{:External}) = 0
encode_llvm(st::EncodeState, ::Ast.DefaultVisibility)  = 0

encode_llvm(st::EncodeState, c::Ast.CConvention) = CallingCov.c

encode_llvm(st::EncodeState, val::Ast.ConstInt) = begin
    v, nbits = val.val, val.nbits
    th = encode_llvm(st, Ast.IntType(val.nbits))
    words = Uint64[(v >> 64w) & 0xffffffffffffffff for w=0:div(nbits-1, 64)]
    return FFI.const_int_arbitrary_precision(th, length(words), words)
end

encode_llvm(st::EncodeState, val::Ast.ConstFloat) = begin
    v = val.val
    nbits = 8 * sizeof(v)
    words = zeros(Uint64, div((nbits - 1), 64) + 1)
    if isa(v, Float16)
        fpsem = FloatSemantics.IEEEHalf
        words[1] = convert(Uint64, reinterpret(Uint16, v))
    elseif isa(v, Float32)
        fpsem = FloatSemantics.IEEESingle
        words[1] = convert(Uint64, reinterpret(Uint32, v))
    elseif isa(v, Float64)
        fpsem = FloatSemantics.IEEEDouble
        words[1] = reinterpret(Uint64, v)
    else
        error("unimplemented")
    end
    FFI.const_float_arbitrary_precision(st.ctx, nbits, words, fpsem)
end

encode_llvm(st::EncodeState, ref::Ast.ConstGlobalRef) =
    get_global(st, ref.name)

encode_llvm(st::EncodeState, inst::Ast.ConstPtrToInt) = begin
    val = encode_llvm(st, inst.op)
    typ = encode_llvm(st, inst.typ)
    return FFI.const_ptrtoint(val, typ)
end

encode_llvm(st::EncodeState, inst::Ast.ConstGetElementPtr) = begin
    addr = encode_llvm(st, inst.addr)
    idxs = encode_llvm(st, inst.idxs)
    return inst.inbounds ? FFI.const_inbounds_getelem_ptr(addr, idxs) :
                           FFI.const_getelem_ptr(addr, idxs)
end

encode_llvm(st::EncodeState, inst::Ast.ConstAdd) = begin
    lhs = encode_llvm(st, inst.op1)
    rhs = encode_llvm(st, inst.op2)
    inst.nsw && return FFI.const_nswadd(lhs, rhs)
    inst.nuw && return FFI.const_nuwadd(lhs, rhs)
    return FFI.const_add(lhs, rhs)
end

encode_llvm(st::EncodeState, inst::Ast.ConstICmp) = begin
    if isa(inst.pred, Ast.SGE)
        pred = IntPred.sge
    else
        error("unimplemented predicate for const icmp")
    end
    lhs = encode_llvm(st, inst.op1)
    rhs = encode_llvm(st, inst.op2)
    return FFI.const_icmp(pred, lhs, rhs)
end

# Encode Operands
encode_llvm(st::EncodeState, op::Ast.ConstOperand) =
    encode_llvm(st, op.val)

# Encode Terminators
encode_llvm(st::EncodeState, term::Ast.Ret) =
    is(term.op, nothing) ? FFI.build_ret_void(st.builder) :
                           FFI.build_ret(st.builder, encode_llvm(st, term.op))

with_sm_diagnostic(f::Function) = begin
    smd = FFI.create_sm_diagnostic()
    try
        f(smd)
    finally
        FFI.dispose_sm_diagnostic(smd)
    end
end

module_from_bitcode(ctx::Context, buf::MemoryBufferPtr) = begin
    modptr = [ModulePtr(C_NULL)]
    outmsg = Ptr{Uint8}[0]
    status = FFI.parse_llvm_bitcode(ctx, buf, modptr, outmsg)
    mod = modptr[1]
    if status != zero(LLVMBool)
        if msg[1] != C_NULL
            err = bytestring(msg[1])
            c_free(msg[1])
            throw(ErrorException(err))
        else
            error("unknown error with `parse_llvm_bitcode`")
        end
    end
    @assert !isnull(mod)
    return mod
end

# llvm takes ownership of the buffer
module_from_bitcode(ctx::Context, bytes::Union(ByteString, IOBuffer)) = begin
    buf = FFI.create_mem_buffer_with_mem_range("<bytes>", bytes.data)
    return module_from_bitcode(ctx, buf)
end

module_from_bitcode(ctx::Context, name::String, bytes::Union(ByteString, IOBuffer)) = begin
    buf = FFI.create_mem_buffer_with_mem_range(name, bytes.data)
    return module_from_bitcode(ctx, buf)
end

module_from_bitcode(ctx::Context, bytes::Vector{Uint8}) = begin
    buf = FFI.create_mem_buffer_with_mem_range("<bytes>", bytes)
    return module_from_bitcode(ctx, buf)
end

module_from_bitcode(ctx::Context, name::String, bytes::Vector{Uint8}) = begin
    buf = FFI.create_mem_buffer_with_mem_range(name, bytes)
    return module_from_bitcode(ctx, buf)
end

module_from_bitcode_file(ctx::Context, path::String) = begin
    buf = FFI.create_mem_buffer_with_contents_of_file(path)
    return module_from_bitcode(ctx, buf)
end

module_to_bitcode(ctx::Context, mod::ModulePtr) = begin
    buf = FFI.with_buff_raw_ostream() do ostream
        FFI.write_llvm_bitcode(ostream, mod)
    end
    return buf
end

module_from_assembly(ctx::Context, buf::MemoryBufferPtr) = begin
    smd = FFI.create_sm_diagnostic()
    mod = FFI.parse_llvm_assembly(ctx, buf, smd)
    try
        isnull(mod) && throw(Diagnostic(smd))
        return mod
    finally
        FFI.dispose_sm_diagnostic(smd)
    end
end

# llvm takes ownership of the buffer
module_from_assembly(ctx::Context, asm::String) = begin
    buf = FFI.create_mem_buffer_with_mem_range("<string>", asm)
    return module_from_assembly(ctx, buf)
end

module_from_assembly(ctx::Context, name::String, asm::String) = begin
    buf = FFI.create_mem_buffer_with_mem_range(name, asm)
    return module_from_assembly(ctx, buf)
end

module_from_assembly_file(ctx::Context, path::String) = begin
    buf = FFI.create_mem_buffer_with_contents_of_file(path)
    return module_from_assembly(ctx, buf)
end

module_to_assembly(ctx::Context, mod::ModulePtr) = begin
    buf = FFI.with_buff_raw_ostream() do ostream
        FFI.write_llvm_assembly(ostream, mod)
    end
    return bytestring(buf)
end

# write LLVM Assembly from a 'ModulePtr' to a file
write_assembly_file(path::String, mod::ModulePtr) = begin
    FFI.with_file_raw_ostream(path, false) do ostream
        FFI.write_llvm_assembly(ostream, mod)
    end
end

# write LLVM Bitcode from a 'ModulePtr' to a file
write_bitcode_file(path::String, mod::ModulePtr) = begin
    FFI.with_file_raw_ostream(path, false) do ostream
        FFI.write_llvm_bitcode(ostream, mod)
    end
end

get_target_triple(ptr::ModulePtr) =
    (s = FFI.get_target_triple(ptr); isempty(s) ? nothing : s)

get_datalayout(ptr::ModulePtr) =
    (s = FFI.get_datalayout(ptr); isempty(s) ? nothing : parse_datalayout(s))

module_from_ast(ctx::Context, mod::Ast.Mod) = begin
    st = EncodeState(ctx)
    mod_ptr = FFI.create_module_with_name_in_ctx(mod.name, st.ctx)
    mod.layout !== nothing && FFI.set_datalayout!(mod_ptr, mod.layout)
    mod.target !== nothing && FFI.set_target_triple!(mod_ptr, mod.target)
    # phase 1 define global definitions
    for def in mod.defs
        if isa(def, Ast.TypeDef)
            error("unimplemented")
        elseif isa(def, Ast.MetadataNodeDef)
            error("unimplemented")
        elseif isa(def, Ast.ModInlineAsm)
            error("unimplemented")
        elseif isa(def, Ast.GlobalDef)
            local g = def.val
            local gptr::GlobalValuePtr
            if isa(g, Ast.GlobalVar)
                gptr = FFI.add_global_in_addr_space!(
                                        mod_ptr,
                                        encode_llvm(st, g.typ),
                                        encode_llvm(st, g.name),
                                        encode_llvm(st, g.addrspace))
                # add global to encoding state
                define_global!(st, g.name, gptr)
            elseif isa(g, Ast.GlobalAlias)
                typ  = encode_llvm(st, g.typ)
                gptr = FFI.just_add_alias(mod_ptr,
                                          encode_llvm(st, g.typ),
                                          encode_llvm(st, g.name))
            elseif isa(g, Ast.Func)
                ftyp = encode_llvm(st,
                    Ast.FuncType(g.rettyp, [p.typ for p in g.params], g.vaargs))
                f = FFI.add_function(mod_ptr, encode_llvm(st, g.name), ftyp)
                define_global!(st, g.name, f)
            end
        end
    end
    for def in mod.defs
        if isa(def, Ast.GlobalDef)
            local g = def.val
            local gptr = get_global(st, g.name)
            if isa(g, Ast.GlobalVar)
                @assert isa(gptr, GlobalValuePtr)
                FFI.set_thread_local!(gptr, g.threadlocal)
                FFI.set_unnamed_addr!(gptr, g.unamedaddr)
                FFI.set_global_constant!(gptr, g.isconst)
                if g.init !== nothing
                    FFI.set_initializer!(gptr, encode_llvm(st, g.init))
                end
                if g.section !== nothing
                    FFI.set_section!(gptr, g.section)
                end
                FFI.set_alignment!(gptr, g.alignment)
            elseif isa(g, Ast.GlobalAlias)
                @assert isa(gptr, GlobalAliasPtr)
                FFI.set_aliasee!(gptr, encode_llvm(st, g.aliasee))
            elseif isa(g, Ast.Func)
                @assert isa(gptr, FunctionPtr)
                FFI.set_func_call_cov!(gptr, encode_llvm(st, g.callingcov))
                FFI.add_func_ret_attr!(gptr, encode_llvm(st, g.retattrs))
                FFI.add_func_attr!(gptr, encode_llvm(st, g.attrs))
                if g.section != nothing
                    FFI.set_section!(gptr, g.section)
                end
                if g.alignment != nothing
                    FFI.set_alignment!(gptr, g.alignment)
                end
                if g.gcname != nothing
                    FFI.set_gc!(gptr, g.gcname)
                end
                for blk in g.blocks
                    b = FFI.append_basicblock_in_ctx(ctx, gptr, encode_llvm(st, blk.name))
                    define_basic_block!(st, g.name, blk.name, b)
                end
                with_locals(st) do st
                    # define and add func parameters
                    pptrs = FFI.get_params(gptr)
                    for p in g.params, pptr in pptrs
                        define_local!(st, g.name, pptr)
                        FFI.set_value_name!(pptr, encode_llvm(st, p.name))
                        if !isempty(p.attrs)
                            FFI.add_attribute!(pptr, encode_llvm(st, p.attrs))
                        end
                    end
                    # build basic blocks
                    for b in g.blocks
                        bptr = st.blocks[b.name]
                        FFI.position_builder_end(st.builder, bptr)
                        # encode basic block instructions
                        for inst in b.insts
                            encode_llvm(st, inst)
                        end
                        # encode basic block terminator
                        encode_llvm(st, b.term)
                    end
                end
                # error out if any forward declared locals have not been realized
                for (k, v) in st.locals
                    isa(v, ForwardVal) && error("local $k is undefined")
                end
            end
            FFI.set_linkage!(gptr, encode_llvm(st, g.linkage))
            FFI.set_visibility!(gptr, encode_llvm(st, g.visibility))
        end
    end
    return mod_ptr
end

get_func_attrs(st::DecodeState, fnptr::FunctionPtr) = begin
    attrs = Ast.ParamAttr[]
    attr = FFI.get_func_attr(fnptr)
    bool(attr & Attribute.naked) && push!(attrs, Ast.Naked())
    bool(attr & Attribute.no_return) && push!(attrs, Ast.NoReturn())
    bool(attr & Attribute.no_unwind) && push!(attrs, Ast.NoUnwind())
    bool(attr & Attribute.read_none) && push!(attrs, Ast.ReadNone())
    bool(attr & Attribute.read_only) && push!(attrs, Ast.ReadOnly())
    bool(attr & Attribute.no_inline) && push!(attrs, Ast.NoInline())
    bool(attr & Attribute.uw_table)  && push!(attrs, Ast.UWTable())
    bool(attr & Attribute.inline_hint) && push!(attrs, Ast.InlineHint())
    bool(attr & Attribute.no_red_zone) && push!(attrs, Ast.NoRedZone())
    bool(attr & Attribute.stack_protect) && push!(attrs, Ast.StackProtect())
    bool(attr & Attribute.always_inline) && push!(attrs, Ast.AlwaysInline())
    bool(attr & Attribute.returns_twice) && push!(attrs, Ast.ReturnsTwice())
    bool(attr & Attribute.stack_alignment)   && push!(attrs, Ast.StackAlignment())
    bool(attr & Attribute.stack_protect_req) && push!(attrs, Ast.StackProtectReq())
    bool(attr & Attribute.optimize_for_size) && push!(attrs, Ast.OptimizeForSize())
    bool(attr & Attribute.no_implicit_float) && push!(attrs, Ast.NoImplicitFloat())
    return attrs
end

get_param_attrs(st::DecodeState, pptr::ParamPtr) = begin
    attrs = Ast.ParamAttr[]
    attr  = FFI.get_attribute(pptr)
    bool(attr & Attribute.s_ext)      && push!(attrs, Ast.SignExt())
    bool(attr & Attribute.in_reg)     && push!(attrs, Ast.InReg())
    bool(attr & Attribute.struct_ret) && push!(attrs, Ast.SRet())
    bool(attr & Attribute.no_alias)   && push!(attrs, Ast.NoAlias())
    bool(attr & Attribute.by_val)     && push!(attrs, Ast.ByVal())
    bool(attr & Attribute.no_capture) && push!(attrs, Ast.NoCapture())
    bool(attr & Attribute.nest)       && push!(attrs, Ast.Nest())
    return attrs
end

get_call_cov(st::DecodeState, fn::FunctionPtr) = begin
    val = FFI.get_func_call_cov(fn)
    val == CallingCov.c    && return Ast.CConvention()
    val == CallingCov.fast && return Ast.FastConvention()
    val == CallingCov.cold && return Ast.ColdConvention()
    error("unhandled calling convention enum value: $val")
end

get_linkage(st::DecodeState, fn::FunctionPtr) = begin
    val = FFI.get_visibility(fn)
    val == 0 && return Ast.Linkage{:External}()
    error("unhandled linkage enum value: $val")
end

get_visibility(st::DecodeState, fn::FunctionPtr) = begin
    val = FFI.get_visibility(fn)
    val == 0 && return Ast.DefaultVisibility()
    error("unhandled visibility enum value: $val")
end

get_params(st::DecodeState, fptr::FunctionPtr) = begin
    ps = Ast.Param[]
    for pptr in FFI.get_params(fptr)
        push!(ps, Ast.Param(decode_llvm(st, FFI.llvm_typeof(pptr)),
                            get_local_name(st, pptr),
                            get_param_attrs(st, pptr)))
    end
    return ps
end

function module_to_ast(ctx::Context, mod_ptr::ModulePtr)
    # lift c++ module to Ast.Module
    @assert ctx.handle == FFI.get_module_ctx(mod_ptr)

    st = DecodeState(ctx)

    moduleid   = FFI.get_module_id(mod_ptr)
    datalayout = get_datalayout(mod_ptr)
    triple     = get_target_triple(mod_ptr)

    # Phase 1; add toplevel global definitions
    add_toplevel(g) = add_global!(st, g)
    map(add_toplevel, FFI.list(GlobalValuePtr,
                               FFI.get_first_global(mod_ptr),
                               FFI.get_next_global))
    map(add_toplevel, FFI.list(GlobalAliasPtr,
                               FFI.get_first_alias(mod_ptr),
                               FFI.get_next_alias))
    map(add_toplevel, FFI.list(FunctionPtr,
                               FFI.get_first_func(mod_ptr),
                               FFI.get_next_func))

    # Phase 2; lift c++ definitions to Ast nodes
    local defs = Ast.Definition[]
    for g in FFI.list(GlobalValuePtr,
                      FFI.get_first_global(mod_ptr),
                      FFI.get_next_global)
        name  = get_global_name(st, g)
        ptrty = decode_llvm(st, FFI.llvm_typeof(g))
        init  = FFI.get_initializer(g)
        var = Ast.GlobalVar(name,
                            FFI.get_linkage(g),
                            FFI.get_visibility(g),
                            FFI.is_thread_local(g),
                            ptrty.addrspace,
                            FFI.has_unnamed_addr(g),
                            FFI.is_global_constant(g),
                            ptrty.typ,
                            !isnull(init) ? decode_llvm(st, init) : nothing,
                            FFI.get_section(g),
                            FFI.get_alignment(g))
        push!(defs, Ast.GlobalDef(var))
    end
    for a in FFI.list(GlobalAliasPtr,
                      FFI.get_first_alias(mod_ptr),
                      FFI.get_next_alias)
        aname = get_global_name(st, a)
        var = Ast.GlobalAlias(aname,
                              FFI.get_linkage(a),
                              FFI.get_visibility(a),
                              FFI.llvm_typeof(a),
                              decode_llvm(st, FFI.get_aliasee(a)))
        push!(defs, Ast.GlobalDef(var))
    end
    for fn in FFI.list(FunctionPtr,
                       FFI.get_first_func(mod_ptr),
                       FFI.get_next_func)
        fname = get_global_name(st, fn)
        ptrty = decode_llvm(st, FFI.llvm_typeof(fn))
        bblocks = Ast.BasicBlock[]
        for bb in FFI.list(BasicBlockPtr,
                           FFI.get_first_basicblock(fn),
                           FFI.get_next_basicblock)
            name  = get_local_name(st, bb)
            iptrs = FFI.list(InstructionPtr,
                             FFI.get_first_instruction(bb),
                             FFI.get_next_instruction)
            insts = Ast.Instruction[]
            if length(iptrs) > 2
                for i=1:length(iptrs)-1
                    push!(insts, decode_llvm(st, iptrs[i]))
                end
            end
            term  = decode_llvm(st, FFI.get_basicblock_terminator(bb))
            push!(bblocks, Ast.BasicBlock(name, insts, term))
        end
        fnty = ptrty.typ
        func = Ast.Func(get_linkage(st, fn),
                        get_visibility(st, fn),
                        get_call_cov(st, fn),
                        get_func_attrs(st, fn),
                        fnty.rettyp,
                        fname,
                        get_params(st, fn),
                        fnty.vaargs,
                        get_func_attrs(st, fn),
                        FFI.get_section(fn),
                        FFI.get_alignment(fn),
                        FFI.get_gc(fn),
                        bblocks)
        push!(defs, Ast.GlobalDef(func))
    end

    # struct definitions
    # module inline asm
    # named metadata nodes
    # metadata definitions

    return Ast.Mod(moduleid, datalayout, triple, defs)
end

# Exe Engine
remove_module(eng::ExeEnginePtr, mod::ModulePtr) = FFI.remove_module(eng, mod)

get_function(eng::ExeEnginePtr, mod::ModulePtr, fname::String) = begin
    fn = FFI.get_named_function(mod, fname)
    isnull(fn) && return nothing
    ptr = FFI.get_ptr_to_global(eng, fn)
    return ptr != C_NULL ? ptr : nothing
end

with_jit(f::Function, mod; optlevel=0) = begin
    @assert optlevel >= 0
    opt = JITCompilerOpts(0, 0, false, false)
    eng = FFI.create_mcjit_compiler_for_module(mod, opt)
    try
        f(eng)
    finally
        !isnull(eng) && FFI.dispose_execution_engine(eng)
    end
end


text:
package com.ellychou.todo.rest.dao;

import com.ellychou.todo.rest.entities.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * User interface mapped to user.xml to manipulate database
 * @author szhou
 * @version 1.0.1
 * @since 2015/2/27
 *
 */
public interface UserDao {
    public int createUser(User user);
    public int updateUser(User user);
    public List<User> getUsers();
    public User getUserById(Long id);
    public User getUserByNameOrEmail(@Param("key")String key, @Param("value")String value);
    public int deleteUserById(Long id);
    public void deleteUsers();

}


text:
<?php

namespace SvnMerge\Exception;

class Command extends \Exception
{
}


text:
<?php
/**
 * require all composer dependencies; requiring the autoload file loads all composer packages at once
 * while this is convenient, this may load too much if your composer configuration grows to many classes
 * if this is a concern, load "/vendor/swiftmailer/autoload.php" instead to load just SwiftMailer
 **/
require_once (dirname(dirname(__DIR__)) . "/vendor/autoload.php");

try {
	// sanitize the inputs from the form: name, email, subject, and message

	// this assumes jQuery (not Angular will be submitting the form, so we're using the $_POST superglobal

	$name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
	$email = filter_input(INPUT_POST, "email", FILTER_SANITIZE_EMAIL);
	$subject = filter_input(INPUT_POST, "subject", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
	$message = filter_input(INPUT_POST, "message", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);

	// create Swift message

	$swiftMessage = Swift_Message::newInstance();

	// attach the sender to the message

	// this takes the form of an associative array where the Email is the key for the real name

	$swiftMessage->setFrom([$email => $name]);

	/**
	 * attach the recipients to the message
	 * notice this an array that can include or omit the the recipient's real name
	 * use the recipients' real name where possible; this reduces the probability of the Email being marked as spam
	 **/
	$recipients = ["samuelvanchandler@gmail.com" => "Samuel Van Chandler"];
	$swiftMessage->setTo($recipients);

	// attach the subject line to the message

	$swiftMessage->setSubject($subject);

	/**
	 * attach the actual message to the message
	 * here, we set two versions of the message: the HTML formatted message and a special filter_var()ed
	 * version of the message that generates a plain text version of the HTML content
	 * notice one tactic used is to display the entire $confirmLink to plain text; this lets users
	 * who aren't viewing HTML content in Emails still access your links
	 **/
	$swiftMessage->setBody($message, "text/html");
	$swiftMessage->addPart(html_entity_decode($message), "text/plain");

	/**
	 * send the Email via SMTP; the SMTP server here is configured to relay everything upstream via CNM
	 * this default may or may not be available on all web hosts; consult their documentation/support for details
	 * SwiftMailer supports many different transport methods; SMTP was chosen because it's the most compatible and has the best error handling
	 * @see http://swiftmailer.org/docs/sending.html Sending Messages - Documentation - SwitftMailer
	 **/
	$smtp = Swift_SmtpTransport::newInstance("localhost", 25);
	$mailer = Swift_Mailer::newInstance($smtp);
	$numSent = $mailer->send($swiftMessage, $failedRecipients);

	/**
	 * the send method returns the number of recipients that accepted the Email
	 * so, if the number attempted is not the number accepted, this is an Exception
	 **/
	if($numSent !== count($recipients)) {
		// the $failedRecipients parameter passed in the send() method now contains contains an array of the Emails that failed

		throw(new RuntimeException("unable to send email"));
	}

	// report a successful send

	echo "
Email successfully sent.
";
} catch(Exception $exception) {
	echo "
Oh snap! Unable to send email: " . $exception->getMessage() . "
";
}


text:
An Idle game I made for a Front-end Developer position. Built with Javascript, HTML, and CSS

[Link to game](https://amir5000.github.io/CowGame)


text:
from troposphere import (
    AWS_REGION,
    And,
    Equals,
    GetAtt,
    If,
    Join,
    Not,
    NoValue,
    Output,
    Ref,
    Split,
    iam
)
from troposphere.certificatemanager import Certificate, DomainValidationOption
from troposphere.cloudfront import (
    DefaultCacheBehavior,
    Distribution,
    DistributionConfig,
    ForwardedValues,
    Origin,
    S3OriginConfig,
    ViewerCertificate
)
from troposphere.s3 import (
    Bucket,
    BucketEncryption,
    CorsConfiguration,
    CorsRules,
    Private,
    PublicAccessBlockConfiguration,
    ServerSideEncryptionByDefault,
    ServerSideEncryptionRule,
    VersioningConfiguration
)

from . import USE_GOVCLOUD
from .common import (
    arn_prefix,
    cmk_arn,
    use_aes256_encryption_cond,
    use_cmk_arn
)
from .domain import domain_name, domain_name_alternates, no_alt_domains
from .sftp import use_sftp_condition, use_sftp_with_kms_condition
from .template import template
from .utils import ParameterWithDefaults as Parameter

assets_bucket_access_control = template.add_parameter(
    Parameter(
        "AssetsBucketAccessControl",
        Default="PublicRead",
        Description="Canned ACL for the public S3 bucket. Private is recommended; it "
                    "allows for objects to be make publicly readable, but prevents "
                    "listing of the bucket contents.",
        Type="String",
        AllowedValues=[
            "PublicRead",
            "Private",
        ],
        ConstraintDescription="Must be PublicRead or Private.",
    ),
    group="Static Media",
    label="Assets Bucket ACL",
)

common_bucket_conf = dict(
    VersioningConfiguration=VersioningConfiguration(
        Status="Enabled"
    ),
    DeletionPolicy="Retain",
    CorsConfiguration=CorsConfiguration(
        CorsRules=[CorsRules(
            AllowedOrigins=Split(";", Join("", [
                "https://", domain_name,
                If(
                    no_alt_domains,
                    # if we don't have any alternate domains, return an empty string
                    "",
                    # otherwise, return the ';https://' that will be needed by the first domain
                    ";https://",
                ),
                # then, add all the alternate domains, joined together with ';https://'
                Join(";https://", domain_name_alternates),
                # now that we have a string of origins separated by ';', Split() is used to make it into a list again
            ])),
            AllowedMethods=[
                "POST",
                "PUT",
                "HEAD",
                "GET",
            ],
            AllowedHeaders=[
                "*",
            ],
        )],
    ),
)

# Create an S3 bucket that holds statics and media. Default to private to prevent
# public list permissions, but still allow objects to be made publicly readable.
assets_bucket = template.add_resource(
    Bucket(
        "AssetsBucket",
        AccessControl=Ref(assets_bucket_access_control),
        BucketEncryption=If(
            use_aes256_encryption_cond,
            BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=ServerSideEncryptionByDefault(
                            SSEAlgorithm='AES256'
                        )
                    )
                ]
            ),
            NoValue
        ),
        **common_bucket_conf,
    )
)

# Output S3 asset bucket name
template.add_output(
    Output(
        "AssetsBucketDomainName",
        Description="Assets bucket domain name",
        Value=GetAtt(assets_bucket, "DomainName"),
    )
)

# Create an S3 bucket that holds user uploads or other non-public files
private_assets_bucket = template.add_resource(
    Bucket(
        "PrivateAssetsBucket",
        AccessControl=Private,
        PublicAccessBlockConfiguration=PublicAccessBlockConfiguration(
            BlockPublicAcls=True,
            BlockPublicPolicy=True,
            IgnorePublicAcls=True,
            RestrictPublicBuckets=True,
        ),
        BucketEncryption=If(
            use_aes256_encryption_cond,
            BucketEncryption(
                ServerSideEncryptionConfiguration=[
                    ServerSideEncryptionRule(
                        ServerSideEncryptionByDefault=ServerSideEncryptionByDefault(
                            SSEAlgorithm=If(use_cmk_arn, 'aws:kms', 'AES256'),
                            KMSMasterKeyID=If(use_cmk_arn, Ref(cmk_arn), Ref("AWS::NoValue")),
                        )
                    )
                ]
            ),
            NoValue
        ),
        **common_bucket_conf,
    )
)

# Output S3 private assets bucket name
template.add_output(
    Output(
        "PrivateAssetsBucketDomainName",
        Description="Private assets bucket domain name",
        Value=GetAtt(private_assets_bucket, "DomainName"),
    )
)

# Bucket for SFTP service
sftp_assets_bucket = Bucket(
    "SFTPAssetsBucket",
    # This bucket intentionally has no Condition (i.e., it is always created,
    # even if SFTP is disabled) because it is referenced throughout the policies
    # and roles in this file.
    AccessControl=Private,
    PublicAccessBlockConfiguration=PublicAccessBlockConfiguration(
        BlockPublicAcls=True,
        BlockPublicPolicy=True,
        IgnorePublicAcls=True,
        RestrictPublicBuckets=True,
    ),
    BucketEncryption=If(
        use_aes256_encryption_cond,
        BucketEncryption(
            ServerSideEncryptionConfiguration=[
                ServerSideEncryptionRule(
                    ServerSideEncryptionByDefault=ServerSideEncryptionByDefault(
                        SSEAlgorithm=If(use_cmk_arn, "aws:kms", "AES256"),
                        KMSMasterKeyID=If(
                            use_cmk_arn, Ref(cmk_arn), Ref("AWS::NoValue")
                        ),
                    )
                )
            ]
        ),
        NoValue,
    ),
    **common_bucket_conf,
)
template.add_resource(sftp_assets_bucket)

# Output SFTP asset bucket name
template.add_output(
    Output(
        "SFTPBucketDomainName",
        Condition=use_sftp_condition,
        Description="SFTP bucket domain name",
        Value=GetAtt(sftp_assets_bucket, "DomainName"),
    )
)

assets_management_policy_statements = [
    dict(
        Effect="Allow",
        Action=["s3:ListBucket"],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(assets_bucket)]),
    ),
    dict(
        Effect="Allow",
        Action=["s3:*"],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(assets_bucket), "/*"]),
    ),
    dict(
        Effect="Allow",
        Action=["s3:ListBucket"],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(private_assets_bucket)]),
    ),
    dict(
        Effect="Allow",
        Action=["s3:*"],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(private_assets_bucket), "/*"]),
    ),
]

assets_management_policy_statements_including_sftp_bucket = (
    assets_management_policy_statements
    + [
        dict(
            Effect="Allow",
            Action=["s3:ListBucket"],
            Resource=Join("", [arn_prefix, ":s3:::", Ref(sftp_assets_bucket)]),
        ),
        dict(
            Effect="Allow",
            Action=["s3:*"],
            Resource=Join("", [arn_prefix, ":s3:::", Ref(sftp_assets_bucket), "/*"]),
        ),
    ]
)

# central asset management policy for use in instance roles
assets_management_policy = iam.Policy(
    PolicyName="AssetsManagementPolicy",
    PolicyDocument=dict(
        Statement=If(
            use_sftp_condition,
            assets_management_policy_statements_including_sftp_bucket,
            assets_management_policy_statements,
        )
    ),
)

if not USE_GOVCLOUD:
    assets_use_cloudfront = template.add_parameter(
        Parameter(
            "AssetsUseCloudFront",
            Description="Whether or not to create a CloudFront distribution tied to the S3 assets bucket.",
            Type="String",
            AllowedValues=["true", "false"],
            Default="true",
        ),
        group="Static Media",
        label="Enable CloudFront",
    )
    assets_use_cloudfront_condition = "AssetsUseCloudFrontCondition"
    template.add_condition(assets_use_cloudfront_condition, Equals(Ref(assets_use_cloudfront), "true"))

    assets_cloudfront_domain = template.add_parameter(
        Parameter(
            "AssetsCloudFrontDomain",
            Description="A custom domain name (CNAME) for your CloudFront distribution, e.g., "
                        "\"static.example.com\".",
            Type="String",
            Default="",
        ),
        group="Static Media",
        label="CloudFront Custom Domain",
    )
    assets_custom_domain_condition = "AssetsCloudFrontDomainCondition"
    template.add_condition(assets_custom_domain_condition, Not(Equals(Ref(assets_cloudfront_domain), "")))

    assets_certificate_arn = template.add_parameter(
        Parameter(
            "AssetsCloudFrontCertArn",
            Description="If (1) you specified a custom static media domain, (2) your stack is NOT in the us-east-1 "
                        "region, and (3) you wish to serve static media over HTTPS, you must manually create an "
                        "ACM certificate in the us-east-1 region and provide its ARN here.",
            Type="String",
            Default="",
        ),
        group="Static Media",
        label="CloudFront SSL Certificate ARN",
    )
    assets_certificate_arn_condition = "AssetsCloudFrontCertArnCondition"
    template.add_condition(assets_certificate_arn_condition, Not(Equals(Ref(assets_certificate_arn), "")))

    # Currently, you can specify only certificates that are in the US East (N. Virginia) region.
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distributionconfig-viewercertificate.html
    assets_create_certificate_condition = "AssetsCreateCertificateCondition"
    template.add_condition(
        assets_create_certificate_condition,
        And(
            Not(Equals(Ref(assets_cloudfront_domain), "")),
            Equals(Ref(AWS_REGION), "us-east-1"),
            Equals(Ref(assets_certificate_arn), "")
        )
    )

    assets_certificate = template.add_resource(
        Certificate(
            'AssetsCertificate',
            Condition=assets_create_certificate_condition,
            DomainName=Ref(assets_cloudfront_domain),
            DomainValidationOptions=[
                DomainValidationOption(
                    DomainName=Ref(assets_cloudfront_domain),
                    ValidationDomain=Ref(assets_cloudfront_domain),
                ),
            ],
        )
    )

    # Create a CloudFront CDN distribution
    distribution = template.add_resource(
        Distribution(
            'AssetsDistribution',
            Condition=assets_use_cloudfront_condition,
            DistributionConfig=DistributionConfig(
                Aliases=If(assets_custom_domain_condition, [Ref(assets_cloudfront_domain)], Ref("AWS::NoValue")),
                # use the ACM certificate we created (if any), otherwise fall back to the manually-supplied
                # ARN (if any)
                ViewerCertificate=If(
                    assets_create_certificate_condition,
                    ViewerCertificate(
                        AcmCertificateArn=Ref(assets_certificate),
                        SslSupportMethod='sni-only',
                    ),
                    If(
                        assets_certificate_arn_condition,
                        ViewerCertificate(
                            AcmCertificateArn=Ref(assets_certificate_arn),
                            SslSupportMethod='sni-only',
                        ),
                        Ref("AWS::NoValue"),
                    ),
                ),
                Origins=[Origin(
                    Id="Assets",
                    DomainName=GetAtt(assets_bucket, "DomainName"),
                    S3OriginConfig=S3OriginConfig(
                        OriginAccessIdentity="",
                    ),
                )],
                DefaultCacheBehavior=DefaultCacheBehavior(
                    TargetOriginId="Assets",
                    ForwardedValues=ForwardedValues(
                        # Cache results *should* vary based on querystring (e.g., 'style.css?v=3')
                        QueryString=True,
                        # make sure headers needed by CORS policy above get through to S3
                        # http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-cors
                        Headers=[
                            'Origin',
                            'Access-Control-Request-Headers',
                            'Access-Control-Request-Method',
                        ],
                    ),
                    ViewerProtocolPolicy="allow-all",
                ),
                Enabled=True
            ),
        )
    )

    # Output CloudFront url
    template.add_output(
        Output(
            "AssetsDistributionDomainName",
            Description="The assets CDN domain name",
            Value=GetAtt(distribution, "DomainName"),
            Condition=assets_use_cloudfront_condition,
        )
    )
else:
    distribution = None

# The scopedown policy is used to restrict a user's access to the parts of the bucket
# we don't want them to access.
common_sftp_scopedown_policy_statements = [
    {
        "Sid": "AllowListingOfSFTPUserFolder",
        "Action": ["s3:ListBucket"],
        "Effect": "Allow",
        "Resource": ["arn:aws:s3:::${transfer:HomeBucket}"],
        "Condition": {
            "StringLike": {
                "s3:prefix": ["${transfer:UserName}/*", "${transfer:UserName}"]
            }
        },
    },
    {
        "Sid": "HomeDirObjectAccess",
        "Effect": "Allow",
        "Action": [
            "s3:PutObject",
            "s3:GetObject",
            "s3:DeleteObjectVersion",
            "s3:DeleteObject",
            "s3:GetObjectVersion",
        ],
        "Resource": [
            Join("/", [GetAtt(sftp_assets_bucket, "Arn"), "${transfer:UserName}"]),
            Join("/", [GetAtt(sftp_assets_bucket, "Arn"), "${transfer:UserName}/*"]),
        ],
    },
]

sftp_kms_policy_statement = dict(
    Effect="Allow",
    Action=["kms:DescribeKey", "kms:GenerateDataKey", "kms:Encrypt", "kms:Decrypt"],
    Resource=Ref(cmk_arn),
)

sftp_scopedown_policy = iam.ManagedPolicy(
    # This is for applying when adding users to the transfer server. It's not used directly in the stack creation,
    # other than adding it to IAM for later use.
    "SFTPUserScopeDownPolicy",
    Condition=use_sftp_condition,
    PolicyDocument=dict(
        Version="2012-10-17",
        Statement=If(
            use_sftp_with_kms_condition,
            common_sftp_scopedown_policy_statements + [sftp_kms_policy_statement],
            common_sftp_scopedown_policy_statements,
        ),
    ),
)
template.add_resource(sftp_scopedown_policy)

# The ROLE is applied to users to let them access the bucket in general,
# without regart to who they are.
common_sftp_user_role_statements = [
    dict(
        Effect="Allow",
        Action=["s3:ListBucket", "s3:GetBucketLocation"],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(sftp_assets_bucket)]),
    ),
    dict(
        Effect="Allow",
        Action=[
            "s3:PutObject",
            "s3:GetObject",
            "s3:DeleteObject",
            "s3:DeleteObjectVersion",
            "s3:GetObjectVersion",
            "s3:GetObjectACL",
            "s3:PutObjectACL",
        ],
        Resource=Join("", [arn_prefix, ":s3:::", Ref(sftp_assets_bucket), "/*"]),
    ),
]

sftp_user_role = iam.Role(
    # This also is not used directly during the stack setup, but is put into IAM
    # to be used later when adding users to the transfer server.
    "SFTPUserRole",
    template=template,
    Condition=use_sftp_condition,
    AssumeRolePolicyDocument=dict(
        Statement=[
            dict(
                Effect="Allow",
                Principal=dict(Service=["transfer.amazonaws.com"]),
                Action=["sts:AssumeRole"],
            )
        ]
    ),
    Policies=[
        iam.Policy(
            "SFTPSUserRolePolicy",
            PolicyName="SFTPSUserRolePolicy",
            PolicyDocument=dict(
                Version="2012-10-17",
                Statement=If(
                    use_sftp_with_kms_condition,
                    common_sftp_user_role_statements + [sftp_kms_policy_statement],
                    common_sftp_user_role_statements,
                ),
            ),
        )
    ],
    RoleName=Join("-", [Ref("AWS::StackName"), "SFTPUserRole"]),
)


text:
PROTOCOL_VERSION='3.2.0'

function process {
	DST_FILE="/etc/group"

	### Status codes
	I_PREVIOUSLY_ADDED_USERS_CHANGED=(0 '${PREVIOUSLY_ADDED_USERS} updated')
	I_PREVIOUSLY_ADDED_USERS_NOT_CHANGED=(0 '${PREVIOUSLY_ADDED_USERS} has not changed')
	I_UPDATED=(0 '${OLD_GROUP} has updated')
	I_NOT_UPDATED=(0 '${OLD_GROUP} has not changed')

	E_GROUP_FILTER=(50 'Error in /etc/group filter')
	E_GROUP_WRONG_GID_RANGES=(51 'Cannot read from the gid ranges file: ${GID_RANGES_FILE}')
	E_GROUP_MERGE=(53 'Error during group file merge')
	E_GROUP_DUPLICATES=(54 'Group names in group file are not uniq: ${DUPLICATE_GROUP_NAMES}')
	E_GID_DUPLICATES=(55 'Group GIDs in group file are not uniq: ${DUPLICATE_GROUP_GIDS}')
	E_GROUP_NO_ROOT=(56 'Missing group "root"')
	E_GROUP_MV_ERROR=(57 '${OLD_GROUP} update failed! {$PREVIOUSLY_ADDED_USERS} may be in incosistent state. Please check it manually.')

	FROM_PERUN="${WORK_DIR}/group"

	OLD_GROUP='/etc/group'
	PREVIOUSLY_ADDED_USERS='/etc/group.perun-added-system-users'
	NOW_ADDED_USERS="${WORK_DIR}/group.perun-added-system-users"
	NEW_GROUP="${WORK_DIR}/group.new" # file must be on same mountpoint for atomic switch

	GID_RANGES_FILE="${WORK_DIR}/gid_ranges"
	if [ ! -r "${GID_RANGES_FILE}" ]; then
		log_msg E_GROUP_WRONG_GID_RANGES
	fi

	create_lock

	#This skripts works in 3:
	# 1. remove groups which are from perun's namepsace from /etc/group (first param)
	# 2. remove all previsously added users from system groups (file PREVIOUSLY_ADDED_USERS)
	# 3. adds groups received from perun
	#       Prints users added to system groups to NOW_ADDED_USERS file
	#
	#
	# usage:  perl -e ${PERL_UPDATE_GROUP} "${OLD_GROUP}" ${FROM_PERUN} >"${NEW_GROUP}"
	#
	# OLD_GROUP - /etc/group
	# FROM_PERUN - group file received from perun
	# prints new group file to STDOUT
	PERL_UPDATE_GROUP_SCRIPT='
	# Script suppose that it get uniqe group names from perun.
	###########################################################

	local $" = ",";
	local $, = ":";
	local $\ = "\n";

	sub isGIDInAllowedRanges {
		my $ranges = shift;
		my $gid = shift;
		foreach my $minimum (sort { $a <=> $b } keys %$ranges) {
			my $maximum = $ranges->{$minimum};
			if($gid >= $minimum && $gid <= $maximum) {
				return 1;
			}
		}
		return 0;
	}

	#Export valid gids from file to hash
	my %validGids;
	open FILE, "'$GID_RANGES_FILE'" or die "Cannot open '$GID_RANGES_FILE': $! \n";
	while (my $row = <FILE>) {
		chomp $row;
		my @parts = split "-", $row;
		my $minimum =  $parts[0];
		my $maximum =  $parts[1];
		$validGids{$minimum} = $maximum;
	}
	close(FILE) or die "Cannot close '$GID_RANGES_FILE': $! \n";

	my %groups;
	my %gids;
	open GROUP, shift @ARGV or die "Cannot open file: $!";
	foreach (<GROUP>) {
		chomp;
		next unless $_; #skip empty lines
		my ($group, $password, $gid, $users) = split ":";
		next if isGIDInAllowedRanges(\%validGids, $gid);
		my %users = map {$_ => 1 }  split ",", $users;
		if(defined $groups{$group}) { die "Duplicate group name: $group\n"; }
		if(defined $gids{$gid}) { die "Duplicate group GID: $gid\n"; }
		$groups{$group} = {
		                   password => $password,
		                   gid => $gid,
		                   users => \%users
		                  };
		$gids{$gid} = 1;
	}
	close GROUP;

	#delete previously added users from system groups
	if( -e "'$PREVIOUSLY_ADDED_USERS'" ) {
		open PREVIOUSLY_ADDED, "<", "'$PREVIOUSLY_ADDED_USERS'" or die "Cant open '$PREVIOUSLY_ADDED_USERS': $!";
		while(<PREVIOUSLY_ADDED>) {
			chomp;
			next unless $_; #skip empty lines
			my ($group, $password, $gid, $users) = split ":";
			if(defined $groups{$group}) {
				if($groups{$group}->{"gid"} != $gid) { die "Consistency error: Gid of group $group changed since last update from $groups{$group}->{qw(gid)} to $gid"; }
				delete @{$groups{$group}->{"users"}}{split ",", $users};
				unless(%{$groups{$group}->{"users"}})  { delete $groups{$group}; delete $gids{$gid};  }
			}
		}
		close PREVIOUSLY_ADDED;
	}

	open NOW_ADDED, ">", "'$NOW_ADDED_USERS'" or die "Cant open '$NOW_ADDED_USERS': $!";
	open FROM_PERUN, shift @ARGV || die "Missing argument." or die "Cant open '$FROM_PERUN': $!";
	while(<FROM_PERUN>) {
		chomp;
		next unless $_; #skip empty lines
		my ($group, $password, $gid, $users) = split ":";
		my %users = map {$_ => 1 }  split ",", $users;
		unless(defined $groups{$group}) {
			if(defined $gids{$gid}) { die "Duplicate group GID: $gid\n" };
			$groups{$group} = {
			                   password => $password,
			                   gid => $gid,
			                   users => \%users
			                  };
			$gids{$gid} = 1;

			unless ( isGIDInAllowedRanges(\%validGids, $gid) ) {
				my @addUsers = keys %users;
				print NOW_ADDED $group, $password, $gid, "@addUsers";
			}
		} else {
			if($gid != $groups{$group}->{qw(gid)}) { die "Group with same name have different gids. Name $group   group GIDs: $gid $groups{$group}->{qw(gid)}\n"; }
			my @addUsers = grep { ! exists $groups{$group}->{"users"}->{$_} } keys %users;
			print NOW_ADDED $group, $password, $gid, "@addUsers";
			@{$groups{$group}->{"users"}}{keys %users} = values %users;  #merge %users and %{$groups{$group}->{qw(users)}} into %{$groups{$group}->{"users"}}
		}
	}
	close NOW_ADDED;
	close FROM_PERUN;

	for my $group (sort { $groups{$a}->{qw(gid)} <=> $groups{$b}->{qw(gid)} } keys %groups) {
		my @users = sort keys %{$groups{$group}->{"users"}};
		print $group, $groups{$group}->{"password"}, $groups{$group}->{"gid"}, "@users";
	}
	'

		catch_error E_GROUP_MERGE perl -e "${PERL_UPDATE_GROUP_SCRIPT}" "${OLD_GROUP}" ${FROM_PERUN} >"${NEW_GROUP}"

		[ -s "${NEW_GROUP}" ] || log_msg E_GROUP_FILTER
		catch_error E_NO_ROOT egrep -q '^root:' "${NEW_GROUP}"

		# check for duplicate group names in new /etc/group
		DUPLICATE_GROUP_NAMES=`cut -d: -f1 "${NEW_GROUP}" | sort | uniq -d`
		[ "x${DUPLICATE_GROUP_NAMES}" == 'x' ] || log_msg E_GROUP_DUPLICATES

		# check for duplicate group GIDs in new /etc/group
		DUPLICATE_GROUP_GIDS=`cut -d: -f3 "${NEW_GROUP}" | sort | uniq -d`
		[ "x${DUPLICATE_GROUP_GIDS}" == 'x' ] || log_msg E_GID_DUPLICATES

		diff_mv_sync "${NOW_ADDED_USERS}" "${PREVIOUSLY_ADDED_USERS}" \
			&& log_msg I_PREVIOUSLY_ADDED_USERS_CHANGED \
			|| log_msg I_PREVIOUSLY_ADDED_USERS_NOT_CHANGED

		mv_chmod "${NEW_GROUP}" "${DST_FILE}" \
			&& log_msg I_UPDATED \
			|| log_msg I_NOT_UPDATED
}


text:
input[type=text], input[type=password], .tagSelector {
	background-color: #FFF;
    -moz-border-radius: 3px;
	border-radius: 3px;
    border: 1px solid #ADB9C2;
    border-top-color: #8496A4;
    border-left-color: #8496A4;
	-moz-box-shadow: inset 1px 1px 3px 0 #CDCDCD;
	-webkit-box-shadow: inset 1px 1px 3px 0 #CDCDCD;
	box-shadow: inset 1px 1px 3px 0 #CDCDCD;
	cursor: text;
    display: inline-block;
	overflow: hidden;
    padding: 4px 6px;
    vertical-align: baseline;
}
.tagSelector input {
	border: none;
	border-radius: 0;
    -moz-border-radius: 0;
	box-shadow: none;
	-moz-box-shadow: none;
	-webkit-box-shadow: none;
	width: auto;
	min-width: 50px;
	float: left;
    padding: 4px 0;
	white-space: nowrap
}
.tagSelector .tag {
	background: #375D81;
	border-radius: 3px;
    -moz-border-radius: 3px;
	color: #FFF;
	float: left;
	height: 15px;
	padding: 0.1em 0.4em 0.5em;
	margin-right: 0.3em;
	margin-bottom: 0.3em;
    vertical-align: baseline;
}
.tagSelector .tag a {
	color: #FFF;
	cursor: pointer;
}
.tagSelector .tag a:hover {
	color: #0099CC;
	text-decoration: none;
}


text:
package jp.ac.nii.prl.mape.redundancy.model;

import java.util.Collection;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.validator.constraints.NotEmpty;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;

@Entity
public class RedundancyView {

	@GeneratedValue
	@Id
	@JsonIgnore
	private Long id;

	@NotEmpty
	@OneToMany(mappedBy="redundancyView")
	private Collection<Instance> instances;

	public Long getId() {
		return id;
	}

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

	@JsonManagedReference
	public Collection<Instance> getInstances() {
		return instances;
	}

	public void setInstances(Collection<Instance> instances) {
		this.instances = instances;
	}

	public void addInstance(Instance instance) {
		instances.add(instance);
	}

}