text:
'use strict';
/**
 * Moving 'brand', 'country', 'funding', 'fullName', 'expMonth', 'expYear' into PaymentMethod.data
 */
const Promise = require('bluebird');

const pick = (obj, attributes) => {
  const res = {};
  attributes.map(attr => {
    res[attr] = obj[attr];
  });
  return res;
};

const updatePaymentMethods = sequelize => {
  const getCollectiveById = id => {
    if (!id) return Promise.resolve(null);
    return sequelize
      .query(`SELECT id, currency FROM "Collectives" WHERE id=:id LIMIT 1`, {
        replacements: { id },
      })
      .then(res => {
        const collective = res.length > 0 && res[0][0];
        return collective;
      });
  };

  const updatePaymentMethod = pm => {
    const data = JSON.stringify(
      Object.assign(
        {},
        pick(pm, [
          'brand',
          'country',
          'funding',
          'fullName',
          'expMonth',
          'expYear',
        ]),
        pm.data,
      ),
    );

    return getCollectiveById(pm.CollectiveId).then(collective => {
      const currency = collective ? collective.currency : null;
      // console.log(">>> updating pm ", pm.id, "data", data, "currency", currency, "collective", collective);
      // return null;
      return sequelize.query(
        `UPDATE "PaymentMethods" SET data=:data, currency=:currency WHERE id=:id`,
        { replacements: { data, id: pm.id, currency } },
      );
    });
  };

  return sequelize
    .query(
      `SELECT * FROM "PaymentMethods" WHERE "CollectiveId" IS NOT NULL AND "expYear" IS NOT NULL`,
      { type: sequelize.QueryTypes.SELECT },
    )
    .then(pms => pms && Promise.map(pms, updatePaymentMethod));
};

module.exports = {
  up: function(queryInterface, DataTypes) {
    return queryInterface
      .addColumn('PaymentMethods', 'currency', { type: DataTypes.STRING(3) })
      .then(() => updatePaymentMethods(queryInterface.sequelize))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'funding'))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'brand'))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'country'))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'fullName'))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'expMonth'))
      .then(() => queryInterface.removeColumn('PaymentMethods', 'expYear'))
      .then(() =>
        queryInterface.renameColumn('PaymentMethods', 'identifier', 'name'),
      );
  },

  down: function(queryInterface, DataTypes) {
    console.log('>>> no downgrade possible');
  },
};


text:
package net.jflask.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IO {

  /**
   * Reads specified input stream until it reaches EOF.
   */
  public static byte[] readFully(InputStream in) throws IOException {
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    pipe(in, bout, false);
    return bout.toByteArray();
  }

  /**
   * Reads input stream until EOF and writes all read data into output stream,
   * then closes it.
   */
  public static void pipe(InputStream in, OutputStream out, boolean closeOutput)
      throws IOException {
    byte[] buf = new byte[1024];
    while (true) {
      int len = in.read(buf);
      if (len >= 0) {
        out.write(buf, 0, len);
        out.flush();
      }
      else {
        if (closeOutput)
          out.close();
        break;
      }
    }
  }

}

redpajama_set_name: RedPajamaGithub


text:
<?php

class Google_Service_Bigquery_Cluster extends Google_Collection
{
  protected $collection_key = 'featureValues';
  public $centroidId;
  public $count;
  protected $featureValuesType = 'Google_Service_Bigquery_FeatureValue';
  protected $featureValuesDataType = 'array';

  public function setCentroidId($centroidId)
  {
    $this->centroidId = $centroidId;
  }
  public function getCentroidId()
  {
    return $this->centroidId;
  }
  public function setCount($count)
  {
    $this->count = $count;
  }
  public function getCount()
  {
    return $this->count;
  }
  /**
   * @param Google_Service_Bigquery_FeatureValue[]
   */
  public function setFeatureValues($featureValues)
  {
    $this->featureValues = $featureValues;
  }
  /**
   * @return Google_Service_Bigquery_FeatureValue[]
   */
  public function getFeatureValues()
  {
    return $this->featureValues;
  }
}


text:
package org.gradle.nativebinaries;

import org.gradle.api.DomainObjectSet;
import org.gradle.api.Incubating;
import org.gradle.runtime.base.ComponentSpec;

/**
 * Represents a logical software component, which may be built in a number of variant binaries.
 */
@Incubating
public interface NativeComponentSpec extends ComponentSpec {
    /**
     * {@inheritDoc}
     */
    DomainObjectSet<NativeBinarySpec> getBinaries();

    /**
     * The name that is used to construct the output file names when building this component.
     */
    String getBaseName();

    /**
     * Sets the name that is used to construct the output file names when building this component.
     */
    void setBaseName(String baseName);
}


text:
import logging
import os
import sys
from argparse import ArgumentParser
import baseline
from torch.nn.parallel import DistributedDataParallel
from torch.utils.data import DataLoader
from eight_mile.utils import str2bool, write_json, Average, Timer, get_num_gpus_multiworker
from baseline.pytorch.embeddings import *
import baseline.embeddings
from eight_mile.optz import *
from eight_mile.pytorch.layers import save_checkpoint, init_distributed
from eight_mile.pytorch.optz import *
from baseline.utils import import_user_module
from mead.api_examples.transformer_utils import MultiFileDatasetReader, on_demand_mlm_masking, get_lr_decay
from baseline.model import create_lang_model
from baseline.pytorch.lm.model import *
from eight_mile.pytorch.serialize import load_tlm_npz

logger = logging.getLogger(__file__)

"""Pre-train a Transformer model in PyTorch

The datasets in this program are read in as an `IterableDataset`, typically one line per sample, which
makes it efficient to process even very large datasets that may not fit in core memory.  The datasets are
assumed to be sharded over a set of files for training and validation.

The `preproc-tlm` script can be used upfront to generate pre-processed representations which allows the reader
to simple ingest the sample without any on demand vectorization or masking.  This approach should be preferred
where available.  To run the model in this manner, first run `preproc-tlm`, generating keys `x` and `y` containing
the numeric one-hot values for each token, and then in this script, pass `--preprocessed true`.

If the model is an MLM and the `preprocessed` value is false, on-demand MLM masking is performed.

"""

def main():
    argv = sys.argv[1:]
    args = parse_args(argv)
    run(**vars(args))

def run(basedir=None, train_file=None, valid_file=None, dataset_key='tlm', embed_type='default',
        d_model=512, d_ff=2048, d_k=None, num_heads=8, num_layers=8, num_train_workers=4,
        nctx=256, file_type='json', batch_size=256, subword_model_file=None, subword_vocab_file=None,
        dropout=0.1, ffn_pdrop=0.0, layer_drop=0.0, lr_scheduler='cosine', lr_decay_steps=None, lr_decay_rate=None,
        lr_alpha=0.0, optim='adamw', lr=4.0e-4, clip=1.0, weight_decay=1.0e-2, epochs=32, restart_from=None,
        restart_tt=None, warmup_steps=10000, saves_per_epoch=10, mlm=True, preprocessed=True, rpr_k=[8],
        rpr_value_on=False, windowed_ra=False, device="cuda", distributed=False, local_rank=-1,
        extra_tokens=["[CLS]", "[MASK]"], do_early_stopping=False, model_type='transformer-mlm', modules=[],
        ra_type=None, transformer_type=None, **kwargs):
    if basedir is None:
        basedir = 'lm-{}-bpe-{}'.format(dataset_key, os.getpid())
    logging.basicConfig(level=logging.INFO if local_rank in [-1, 0] else logging.WARN)

    for module in modules:
        import_user_module(module)
    num_gpus = get_num_gpus_multiworker()
    distributed = distributed or num_gpus > 1
    logger.info(f"Using {num_gpus} GPUs in this job.")

    do_on_demand_masking = mlm and not preprocessed
    if do_on_demand_masking:
        logger.info(f"On-demand masking is turned on")
    if distributed:
        device, updated_local_rank = init_distributed(local_rank)
        local_rank = updated_local_rank

    if file_type == 'tfrecord':
        reader_type = 'tfrecord'
    elif preprocessed:
        reader_type = 'preprocessed'
    else:
        reader_type = 'lang'
    reader = MultiFileDatasetReader(src_nctx=nctx, model_file=subword_model_file,
                                    vocab_file=subword_vocab_file, file_type=file_type,
                                    reader_type=reader_type, record_keys=['x', 'y'] if mlm else ['x'],
                                    extra_tokens=extra_tokens)

    # This looks a bit funny but the streaming reader ignores our vocab and gives us the one from the subword_model
    # However, we do need to get counts from our dataset for validation so we can calculate the perplexity
    vocab = reader.build_vocab([valid_file])
    # If we are not using chars, then use 'x' for both input and output
    preproc_data = baseline.embeddings.load_embeddings('x', dsz=d_model, known_vocab=vocab['x'],
                                                       preserve_vocab_indices=True,
                                                       embed_type=embed_type)
    vocabs = preproc_data['vocab']

    os.makedirs(basedir, exist_ok=True)
    # We want to make sure to save our input vocab into the basedir for reuse later
    write_json(vocabs, os.path.join(basedir, 'vocabs.json'))
    embeddings = {'x': preproc_data['embeddings']}
    logger.info("Loaded embeddings")

    train_set = reader.load(train_file, vocabs)
    valid_set = reader.load(valid_file, vocabs, distribute=False, shuffle=False)

    train_loader = DataLoader(train_set, batch_size=batch_size, num_workers=num_train_workers)
    valid_loader = DataLoader(valid_set, batch_size=batch_size)
    logger.info("Loaded datasets")
    logger.info("Using embedding type [%s]", embed_type)

    if 'mlm' in model_type:
        mask_from = vocabs
        vocab_size = len(mask_from)
        mask_value = mask_from.get("[MASK]")
        if mask_value == -1:
            logger.error("We could not find a suitable masking token in the vocab")
            return

    if len(rpr_k) == 0 or rpr_k[0] < 1:
        rpr_k = None
    elif len(rpr_k) == 1:
        rpr_k = None if rpr_k[0] == 0 else rpr_k[0]
    if ra_type != None and ra_type != 'shaw' and rpr_k is not None:
        print(f"Relative attention mismatch. You requested {ra_type} with rpr set.  Setting it to 0")
        rpr_k = None

    model = create_lang_model(
        embeddings,
        hsz=d_model,
        nctx=nctx,  # Only for gMLP
        d_ff=d_ff,
        tie_weights=True,
        dropout=dropout,
        gpu=False,
        num_heads=num_heads,
        layers=num_layers,
        rpr_k=rpr_k,
        d_k=d_k,
        ffn_pdrop=ffn_pdrop,
        windowed_ra=windowed_ra,
        rpr_value_on=rpr_value_on,
        layer_drop=layer_drop,
        model_type=model_type,
        ra_type=ra_type,
        transformer_type=transformer_type,
        src_keys=['x'], tgt_key='x')
    model.to(device)

    loss_function = model.create_loss()
    loss_function.to(device)

    logger.info("Loaded model and loss")

    steps_per_epoch = len(train_loader) // num_gpus
    update_on = steps_per_epoch // saves_per_epoch
    report_on = max(10, update_on) // 10
    logger.info(f"Steps per epoch per GPU: {steps_per_epoch}. Saving checkpoint every {update_on} steps.")
    lr_decay = get_lr_decay(lr_scheduler, lr, steps_per_epoch, epochs, logger,
                            decay_steps=lr_decay_steps, decay_rate=lr_decay_rate, alpha=lr_alpha)
    linear_warmup = WarmupLinearSchedulerPyTorch(warmup_steps, lr=lr)
    lr_sched = CompositeLRScheduler(linear_warmup, lr_decay, lr=lr)

    global_step = 0
    start_epoch = 0
    if restart_from:

        if restart_from.endswith('npz'):
            load_tlm_npz(model, restart_from)
        else:
            model.load_state_dict(torch.load(restart_from))
        vec = restart_from.split("-")

        if restart_tt:
            tick_type = restart_tt
        else:
            tick_type = vec[-2]
        step_num = int(vec[-1].split(".")[0])
        if tick_type == 'epoch':
            start_epoch = step_num
            global_step = start_epoch * steps_per_epoch

        elif tick_type == 'step':
            start_epoch = step_num // steps_per_epoch
            global_step = step_num
        else:
            logger.warning(f"The previous tick was {step_num} but command-line specifies to ignore, setting to 0")

        logger.info("Restarting from a previous checkpoint %s.\n\tStarting at global_step=%d, epoch=%d",
                    restart_from, global_step, start_epoch + 1)

    optimizer = OptimizerManager(model, global_step, optim=optim, lr=lr, lr_function=lr_sched,
                                 weight_decay=weight_decay)
    logger.info("Model has {:,} parameters".format(sum(p.numel() for p in model.parameters() if p.requires_grad)))

    # Prepare model for distributed training if needed
    if distributed:
        # This program assume pure data parallelism, each model is on a single gpu
        # If we wanted to support model and data parallelism we would need to update
        # the selection of gpus based on rank, it would need to select multiple ids
        # based on rank, here we select only a single gpu and use it for input and
        # output.
        model = DistributedDataParallel(model, device_ids=[device], output_device=device, find_unused_parameters=True)
        logger.info("Model located on %s", device)

    model_base = os.path.join(basedir, 'checkpoint')
    steps = global_step
    best_valid_loss = np.inf

    timer = Timer()
    for epoch in range(start_epoch, epochs):
        avg_loss = Average('average_train_loss')
        metrics = {}
        optimizer.zero_grad()
        timer.start()
        model.train()
        train_itr = iter(train_loader)
        for i in range(steps_per_epoch):
            batch = next(train_itr)
            steps += 1
            x, y = batch
            inputs = x.to(device)
            labels = y.to(device)
            if do_on_demand_masking:
                inputs, labels, _ = on_demand_mlm_masking(inputs, labels, mask_value, vocab_size)
            inputs = {'x': inputs}

            labels = labels.contiguous()
            logits = model(inputs, None)[0].contiguous()
            if mlm:
                loss = loss_function(logits, labels)
            else:
                shift_logits = logits[:, -1]
                shift_labels = labels[:, 1:]
                loss = loss_function(shift_logits, shift_labels)
            loss.backward()
            avg_loss.update(loss.item())

            torch.nn.utils.clip_grad_norm_(model.parameters(), clip)
            optimizer.step()
            optimizer.zero_grad()
            if (i + 1) % report_on == 0:
                logging.info(avg_loss)

            if (i + 1) % update_on == 0 and local_rank < 1:
                elapsed = timer.elapsed(True)
                logging.info('elapsed time this epoch %d min', elapsed)
                logging.info('elapsed step time %f steps/min', i / elapsed)
                logging.info('LR: %f', optimizer.current_lr)

                if not do_early_stopping:
                    save_checkpoint(model, model_base, steps, tick_type='step')
                else:
                    valid_token_loss = validate(model, loss_function, valid_loader, avg_loss, timer, metrics,
                                                do_on_demand_masking, mlm, mask_value, vocab_size, device)
                    if valid_token_loss < best_valid_loss:
                        best_valid_loss = valid_token_loss
                        logger.info(f"New best valid loss: {best_valid_loss}. Saving checkpoint...")
                        save_checkpoint(model, model_base, steps, tick_type='step')
                    model.train()

        if not do_early_stopping:
            _ = validate(model, loss_function, valid_loader, avg_loss, timer, metrics, do_on_demand_masking, mlm,
                         mask_value, vocab_size, device)
            save_checkpoint(model, model_base, epoch, tick_type='epoch')

def validate(model, loss_function, valid_loader, avg_train_loss, train_timer, metrics, do_on_demand_masking, mlm,
             mask_value, vocab_size, device):
    train_token_loss = avg_train_loss.avg
    # This is the average training token-level loss across all machines
    # This is the token-level training perplexity
    train_token_ppl = math.exp(train_token_loss)
    metrics['train_elapsed_min'] = train_timer.elapsed(True)
    metrics['average_train_loss'] = train_token_loss
    metrics['train_ppl'] = train_token_ppl

    avg_valid_loss = Average('average_valid_loss')
    valid_timer = Timer()
    valid_timer.start()
    model.eval()
    valid_steps = len(valid_loader)
    valid_itr = iter(valid_loader)
    for j in range(valid_steps):
        batch = next(valid_itr)
        with torch.no_grad():
            x, y = batch
            inputs = x.to(device)
            labels = y.to(device)

            if do_on_demand_masking:
                inputs, labels, _ = on_demand_mlm_masking(inputs, labels, mask_value, vocab_size)
            inputs = {'x': inputs}
            labels = labels.contiguous()
            logits = model(inputs, None)[0].contiguous()
            if mlm:
                loss = loss_function(logits, labels)
            else:
                shift_logits = logits[:, -1]
                shift_labels = labels[:, 1:]
                loss = loss_function(shift_logits, shift_labels)

            avg_valid_loss.update(loss.item())

    valid_token_loss = avg_valid_loss.avg
    valid_token_ppl = math.exp(valid_token_loss)

    metrics['valid_elapsed_min'] = valid_timer.elapsed(True)
    metrics['average_valid_loss'] = valid_token_loss
    metrics['average_valid_word_ppl'] = valid_token_ppl
    logger.info(metrics)
    return valid_token_loss

def parse_args(argv):
    parser = ArgumentParser()
    parser.add_argument("--basedir", type=str)
    parser.add_argument("--train_file", type=str, required=True, help='File path to use for train file')
    parser.add_argument("--valid_file", type=str, required=True, help='File path to use for valid file')
    parser.add_argument("--dataset_key", default="tlm",
                        help="dataset key for basedir")
    parser.add_argument("--embed_type", type=str, default='default',
                        choices=["default", "positional", "learned-positional"],
                        help="register label of the embeddings")
    parser.add_argument('--modules', nargs="+", default=[])
    parser.add_argument("--d_model", type=int, default=512, help="Model dimension (and embedding dsz)")
    parser.add_argument("--d_ff", type=int, default=2048, help="FFN dimension")
    parser.add_argument("--d_k", type=int, default=None, help="Dimension per head.  Use if num_heads=1 to reduce dims")
    parser.add_argument("--num_heads", type=int, default=8, help="Number of heads")
    parser.add_argument("--num_layers", type=int, default=8, help="Number of layers")
    parser.add_argument("--num_train_workers", type=int, default=4, help="Number train workers")
    parser.add_argument("--nctx", type=int, default=256, help="Max input length")
    parser.add_argument("--file_type", default='json', help="Glob pattern for data")
    parser.add_argument("--batch_size", type=int, default=256, help="Batch Size")
    parser.add_argument("--subword_model_file", type=str, help="The BPE model file", required=True)
    parser.add_argument("--subword_vocab_file", type=str, help="The BPE subword vocab", required=True)
    parser.add_argument("--subword_type", type=str, choices=["bpe", "wordpiece", "sentencepiece"], default="bpe")
    parser.add_argument("--dropout", type=float, default=0.1, help="Dropout")
    parser.add_argument("--ffn_pdrop", type=float, default=0.0, help="Dropout in the dense stack")
    parser.add_argument("--layer_drop", type=float, default=0.0, help="LayerDrop to apply")
    parser.add_argument("--lr_scheduler", type=str, default='cosine', help="The type of learning rate decay scheduler")
    parser.add_argument("--lr_decay_steps", type=int, help="decay steps of lr scheduler")
    parser.add_argument("--lr_decay_rate", type=float, help="decay rate of lr scheduler")
    parser.add_argument("--lr_alpha", type=float, help="parameter alpha for cosine decay scheduler")
    parser.add_argument("--optim", default="adamw", type=str, help="Optimizer to use (defaults to adamw)")
    parser.add_argument("--lr", type=float, default=4.0e-4, help="Learning rate")
    parser.add_argument("--clip", type=float, default=1.0, help="Clipping gradient norm")
    parser.add_argument("--weight_decay", type=float, default=1.0e-2, help="Weight decay")
    parser.add_argument("--epochs", type=int, default=32, help="Num training epochs")
    parser.add_argument("--restart_from", type=str, help="Option allows you to restart from a previous checkpoint")
    parser.add_argument("--restart_tt", type=str, help="Optional param for legacy checkpoints",
                        choices=['step', 'epoch', 'ignore'])
    parser.add_argument("--warmup_steps", type=int, default=10000, help="Num warmup steps")
    parser.add_argument("--saves_per_epoch", type=int, default=10, help="The number of checkpoints to save per epoch")
    parser.add_argument("--model_type", type=str, default="transformer-mlm")
    parser.add_argument("--preprocessed", type=str2bool, default=True, help="Has the data already been preprocessed?")
    parser.add_argument('--rpr_k',
                        help='Relative attention positional sizes pass 0 if you dont want relative attention',
                        type=int, default=[8], nargs='+')
    parser.add_argument('--rpr_value_on', type=str2bool, default=False,
                        help="In relative attention, whether add positional correction to values in addition to the "
                             "correction to attention matrix")
    parser.add_argument("--ra_type", type=str, help='Select a relative attention type')
    parser.add_argument("--windowed_ra", type=str2bool, default=False, help="whether prevent attention beyond rpr_k")
    parser.add_argument("--device", type=str,
                        default="cuda" if torch.cuda.is_available() else "cpu",
                        help="Device (cuda or cpu)")
    parser.add_argument("--distributed",
                        type=str2bool,
                        default=False,
                        help="Are we doing distributed training?")
    parser.add_argument("--local_rank",
                        type=int,
                        default=-1,
                        help="Local rank for distributed training (-1 means use the environment variables to find)")
    parser.add_argument("--extra_tokens", help="What extra tokens should we use", nargs="+",
                        default=["[CLS]", "[MASK]"])
    parser.add_argument("--do_early_stopping", type=str2bool, default=False,
                        help="if True, only save checkpoint when valid loss improves")
    parser.add_argument("--transformer_type", help="What TransformerEncoder type to use")

    args = parser.parse_args(argv)
    return args

if __name__ == "__main__":
    main()


text:
package com.ge.protein.util;

public final class Constants {

    private Constants() {
        throw new AssertionError("No construction for constant class");
    }

    public static final String DEFAULT_SHARED_PREFERENCES = "default_shared_preferences";

    public static final String ACCESS_TOKEN_KEY = "access_token";

    public static final String USER = "user";

}


text:
package org.apache.flink.util;

import org.slf4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

/**
 * An utility class for I/O related functionality.
 */
public final class IOUtils {

	/** The block size for byte operations in byte. */
	private static final int BLOCKSIZE = 4096;

	// ------------------------------------------------------------------------
	//  Byte copy operations
	// ------------------------------------------------------------------------

	/**
	 * Copies from one stream to another.
	 *
	 * @param in
	 *        InputStream to read from
	 * @param out
	 *        OutputStream to write to
	 * @param buffSize
	 *        the size of the buffer
	 * @param close
	 *        whether or not close the InputStream and OutputStream at the end. The streams are closed in the finally
	 *        clause.
	 * @throws IOException
	 *         thrown if an error occurred while writing to the output stream
	 */
	public static void copyBytes(final InputStream in, final OutputStream out, final int buffSize, final boolean close)
			throws IOException {

		@SuppressWarnings("resource")
		final PrintStream ps = out instanceof PrintStream ? (PrintStream) out : null;
		final byte[] buf = new byte[buffSize];
		try {
			int bytesRead = in.read(buf);
			while (bytesRead >= 0) {
				out.write(buf, 0, bytesRead);
				if ((ps != null) && ps.checkError()) {
					throw new IOException("Unable to write to output stream.");
				}
				bytesRead = in.read(buf);
			}
		} finally {
			if (close) {
				out.close();
				in.close();
			}
		}
	}

	/**
	 * Copies from one stream to another. closes the input and output
	 * streams at the end.
	 *
	 * @param in
	 *        InputStream to read from
	 * @param out
	 *        OutputStream to write to
	 * @throws IOException
	 *         thrown if an I/O error occurs while copying
	 */
	public static void copyBytes(final InputStream in, final OutputStream out) throws IOException {
		copyBytes(in, out, BLOCKSIZE, true);
	}

	/**
	 * Copies from one stream to another.
	 *
	 * @param in
	 *        InputStream to read from
	 * @param out
	 *        OutputStream to write to
	 * @param close
	 *        whether or not close the InputStream and OutputStream at the
	 *        end. The streams are closed in the finally clause.
	 * @throws IOException
	 *         thrown if an I/O error occurs while copying
	 */
	public static void copyBytes(final InputStream in, final OutputStream out, final boolean close) throws IOException {
		copyBytes(in, out, BLOCKSIZE, close);
	}

	// ------------------------------------------------------------------------
	//  Stream input skipping
	// ------------------------------------------------------------------------

	/**
	 * Reads len bytes in a loop.
	 *
	 * @param in
	 *        The InputStream to read from
	 * @param buf
	 *        The buffer to fill
	 * @param off
	 *        offset from the buffer
	 * @param len
	 *        the length of bytes to read
	 * @throws IOException
	 *         if it could not read requested number of bytes for any reason (including EOF)
	 */
	public static void readFully(final InputStream in, final byte[] buf, int off, final int len)
			throws IOException {
		int toRead = len;
		while (toRead > 0) {
			final int ret = in.read(buf, off, toRead);
			if (ret < 0) {
				throw new IOException("Premeture EOF from inputStream");
			}
			toRead -= ret;
			off += ret;
		}
	}

	/**
	 * Similar to readFully(). Skips bytes in a loop.
	 *
	 * @param in
	 *        The InputStream to skip bytes from
	 * @param len
	 *        number of bytes to skip
	 * @throws IOException
	 *         if it could not skip requested number of bytes for any reason (including EOF)
	 */
	public static void skipFully(final InputStream in, long len) throws IOException {
		while (len > 0) {
			final long ret = in.skip(len);
			if (ret < 0) {
				throw new IOException("Premeture EOF from inputStream");
			}
			len -= ret;
		}
	}

	// ------------------------------------------------------------------------
	//  Silent I/O cleanup / closing
	// ------------------------------------------------------------------------

	/**
	 * Close the AutoCloseable objects and ignore any {@link Exception} or
	 * null pointers. Must only be used for cleanup in exception handlers.
	 *
	 * @param log
	 *        the log to record problems to at debug level. Can be null.
	 * @param closeables
	 *        the objects to close
	 */
	public static void cleanup(final Logger log, final AutoCloseable... closeables) {
		for (AutoCloseable c : closeables) {
			if (c != null) {
				try {
					c.close();
				} catch (Exception e) {
					if (log != null && log.isDebugEnabled()) {
						log.debug("Exception in closing " + c, e);
					}
				}
			}
		}
	}

	/**
	 * Closes the stream ignoring {@link IOException}. Must only be called in
	 * cleaning up from exception handlers.
	 *
	 * @param stream
	 *        the stream to close
	 */
	public static void closeStream(final java.io.Closeable stream) {
		cleanup(null, stream);
	}

	/**
	 * Closes the socket ignoring {@link IOException}.
	 *
	 * @param sock
	 *        the socket to close
	 */
	public static void closeSocket(final Socket sock) {
		// avoids try { close() } dance
		if (sock != null) {
			try {
				sock.close();
			} catch (IOException ignored) {
			}
		}
	}

	/**
	 * Closes all {@link AutoCloseable} objects in the parameter, suppressing exceptions. Exception will be emitted
	 * after calling close() on every object.
	 *
	 * @param closeables iterable with closeables to close.
	 * @throws Exception collected exceptions that occurred during closing
	 */
	public static void closeAll(Iterable<? extends AutoCloseable> closeables) throws Exception {
		if (null != closeables) {

			Exception collectedExceptions = null;

			for (AutoCloseable closeable : closeables) {
				try {
					if (null != closeable) {
						closeable.close();
					}
				} catch (Exception e) {
					collectedExceptions = ExceptionUtils.firstOrSuppressed(collectedExceptions, e);
				}
			}

			if (null != collectedExceptions) {
				throw collectedExceptions;
			}
		}
	}

	/**
	 * Closes all elements in the iterable with closeQuietly().
	 */
	public static void closeAllQuietly(Iterable<? extends AutoCloseable> closeables) {
		if (null != closeables) {
			for (AutoCloseable closeable : closeables) {
				closeQuietly(closeable);
			}
		}
	}

	/**
	 * Closes the given AutoCloseable.
	 *
	 *
Important: This method is expected to never throw an exception.
	 */
	public static void closeQuietly(AutoCloseable closeable) {
		try {
			if (closeable != null) {
				closeable.close();
			}
		} catch (Throwable ignored) {}
	}

	// ------------------------------------------------------------------------

	/**
	 * Private constructor to prevent instantiation.
	 */
	private IOUtils() {}
}


text:
typedef std::atomic_flag sx_lock_t;
#define sx_lock(_l)     while(_l.test_and_set(std::memory_order_acquire)) bx::yield()
#define sx_unlock(_l)   _l.clear(std::memory_order_release)
class ScopedLock
{
public:
    explicit ScopedLock(sx_lock_t& l) : m_lock(l) {
        sx_lock(l);
    }

    ~ScopedLock()
    {
        sx_unlock(m_lock);
    }

private:
    sx_lock_t& m_lock;
};

#define MEM_POOL_BUCKET_SIZE 256
#define IMGUI_VIEWID 255
#define NANOVG_VIEWID 254
#define LOG_STRING_SIZE 256
#define RANDOM_NUMBER_POOL 10000

#define T_ENC_SIGN 0x54454e43        // "TENC"
#define T_ENC_VERSION TEE_MAKE_VERSION(1, 0)

#if BX_PLATFORM_IOS || BX_PLATFORM_OSX
uint8_t iosGetCoreCount();
void iosGetCacheDir(bx::Path* pPath);
void iosGetDataDir(bx::Path* pPath);
#endif

typedef std::chrono::high_resolution_clock TClock;
typedef std::chrono::high_resolution_clock::time_point TClockTimePt;

namespace tee {
// default AES encryption keys
static const uint8_t kAESKey[] = {0x32, 0xBF, 0xE7, 0x76, 0x41, 0x21, 0xF6, 0xA5, 0xEE, 0x70, 0xDC, 0xC8, 0x73, 0xBC, 0x9E, 0x37};
static const uint8_t kAESIv[] = {0x0A, 0x2D, 0x76, 0x63, 0x9F, 0x28, 0x10, 0xCD, 0x24, 0x22, 0x26, 0x68, 0xC1, 0x5A, 0x82, 0x5A};

//
struct FrameData
{
    uint64_t frame;
    uint32_t renderFrame;
    double frameTime;
    double fps;
    double elapsedTime;
    double avgFrameTime;
    TClockTimePt lastFrameTimePt;
    double frameTimes[32];
    double fpsTime;
};

struct HeapMemoryImpl
{
    MemoryBlock m;
    volatile int32_t refcount;
    bx::AllocatorI* alloc;

    HeapMemoryImpl()
    {
        m.data = nullptr;
        m.size = 0;
        refcount = 1;
        alloc = nullptr;
    }
};

#pragma pack(push, 1)
struct EncodeHeader
{
    uint32_t sign;
    uint32_t version;
    int decodeSize;
    int uncompSize;
};
#pragma pack(pop)

class GfxDriverEvents : public GfxDriverEventsI
{
private:
    bx::Lock m_lock;

public:
    void onFatal(GfxFatalType::Enum type, const char* str) override;
    void onTraceVargs(const char* filepath, int line, const char* format, va_list argList) override;

    uint32_t onCacheReadSize(uint64_t id) override
    {
        return 0;
    }

    bool onCacheRead(uint64_t id, void* data, uint32_t size) override
    {
        return false;
    }

    void onCacheWrite(uint64_t id, const void* data, uint32_t size) override
    {
    }

    void onScreenShot(const char *filePath, uint32_t width, uint32_t height, uint32_t pitch,
                      const void *data, uint32_t size, bool yflip) override
    {
    }

    void onCaptureBegin(uint32_t width, uint32_t height, uint32_t pitch, TextureFormat::Enum fmt, bool yflip) override
    {
    }

    void onCaptureEnd() override
    {
    }

    void onCaptureFrame(const void* data, uint32_t size) override
    {
    }
};

struct LogCache
{
    LogType::Enum type;
    char text[LOG_STRING_SIZE];
};

struct ConsoleCommand
{
    size_t cmdHash;
    std::function<void(int, const char**)> callback;
    ConsoleCommand() : cmdHash(0) {}
};

struct Tee
{
    UpdateCallback updateFn;
    Config conf;
    RendererApi* renderer;
    FrameData frameData;
    double timeMultiplier;
    bx::Pool<HeapMemoryImpl> memPool;
    //bx::Lock memPoolLock;
    sx_lock_t memPoolLock;
    GfxDriver* gfxDriver;
    IoDriverDual* ioDriver;
    PhysDriver2D* phys2dDriver;
    SimpleSoundDriver* sndDriver;
    PageAllocator tempAlloc;
    GfxDriverEvents gfxDriverEvents;
    LogCache* gfxLogCache;
    int numGfxLogCache;

    std::random_device randDevice;
    std::mt19937 randEngine;
    int* randomPoolInt;
    float* randomPoolFloat;
    volatile int32_t randomIntOffset;
    volatile int32_t randomFloatOffset;

    Remotery* rmt;
    bx::Array<ConsoleCommand> consoleCmds;

    bool init;
    bool gfxReset;

    Tee() :
        tempAlloc(TEE_MEMID_TEMP),
        randEngine(randDevice())
    {
        gfxDriver = nullptr;
        phys2dDriver = nullptr;
        sndDriver = nullptr;
        updateFn = nullptr;
        renderer = nullptr;
        ioDriver = nullptr;
        timeMultiplier = 1.0;
        gfxLogCache = nullptr;
        numGfxLogCache = 0;
        rmt = nullptr;
        init = false;
        gfxReset = false;
        bx::memSet(&frameData, 0x00, sizeof(frameData));
        randomFloatOffset = randomIntOffset = 0;
        randomPoolFloat = nullptr;
        randomPoolInt = nullptr;
        memPoolLock.clear();
    }
};

#if defined(_DEBUG)
static bx::LeakCheckAllocator gAllocStub;
#else
static bx::DefaultAllocator gAllocStub;
#endif
static bx::AllocatorI* gAlloc = &gAllocStub;

static bx::TraceAllocator* gTraceAlloc = nullptr;
static bx::AllocatorI* gPrevAlloc = nullptr;

// Global variables that must be set before initializing the engine
// Some of these values are set in their platform specific units
static bx::Path gDataDir;
static bx::Path gCacheDir;
static bx::String32 gPackageVersion("0.0.0");
static HardwareInfo gHwInfo;
static bool gHasHardwareKey = false;        // Used for android devices
static Tee* gTee = nullptr;

void platformSetVars(const char* dataDir, const char* cacheDir, const char* version)
{
    BX_ASSERT(dataDir && cacheDir, "");
    gDataDir = dataDir;
    gCacheDir = cacheDir;
    if (version)
        gPackageVersion = version;
}

void platformSetHwInfo(const HardwareInfo& hwinfo)
{
    bx::memCopy(&gHwInfo, &hwinfo, sizeof(HardwareInfo));
}

void platformSetHardwareKey(bool hasHardwareKey)
{
    gHasHardwareKey = hasHardwareKey;
}

void platformSetGfxReset(bool gfxReset)
{
    if (gTee)
        gTee->gfxReset = gfxReset;
}

static void* remoteryMallocCallback(void* mm_context, rmtU32 size)
{
    return BX_ALLOC(gAlloc, size);
}

static void remoteryFreeCallback(void* mm_context, void* ptr)
{
    BX_FREE(gAlloc, ptr);
}

static void* remoteryReallocCallback(void* mm_context, void* ptr, rmtU32 size)
{
    return BX_REALLOC(gAlloc, ptr, size);
}

static void remoteryInputHandlerCallback(const char* text, void* context)
{
    BX_ASSERT(gTee);

    const int maxArgs = 16;
    bx::String64 args[maxArgs];
    char cmdText[2048];
    bx::strCopy(cmdText, sizeof(cmdText), text);
    char* token = strtok(cmdText, " ");
    int numArgs = 0;
    while (token && numArgs < maxArgs) {
        args[numArgs++] = token;
        token = strtok(nullptr, " ");
    }

    if (numArgs > 0) {
        // find and execute command
        size_t cmdHash = tinystl::hash_string(args[0].cstr(), args[0].getLength());
        for (int i = 0; i < gTee->consoleCmds.getCount(); i++) {
            if (gTee->consoleCmds[i].cmdHash == cmdHash) {
                const char* cargs[maxArgs];
                for (int k = 0; k < numArgs; k++)
                    cargs[k] = args[k].cstr();

                gTee->consoleCmds[i].callback(numArgs, cargs);
                break;
            }
        }
    }
}

bool init(const Config& conf, UpdateCallback updateFn, const GfxPlatformData* platform)
{
    if (gTee) {
        BX_ASSERT(false);
        return false;
    }

    json::HeapAllocator::SetAlloc(gAlloc);

    // Switch memory manager to our TraceAllocator
#if 0
    if (BX_ENABLED(termite_DEV)) {
        BX_VERBOSE("Using trace allocator");
        gTraceAlloc = BX_NEW(gAlloc, bx::TraceAllocator)(gAlloc, 1, 256);
        gPrevAlloc = gAlloc;
        gAlloc = gTraceAlloc;
    }
#endif

    gTee = BX_NEW(gAlloc, Tee);
    if (!gTee)
        return false;

    memcpy(&gTee->conf, &conf, sizeof(gTee->conf));

    // Hardware stats
#if BX_PLATFORM_IOS || BX_PLATFORM_OSX
    gHwInfo.numCores = iosGetCoreCount();
#else
    gHwInfo.numCores = std::thread::hardware_concurrency();
#endif

    gTee->updateFn = updateFn;

    // Set Data and Cache Dir paths
#if BX_PLATFORM_WINDOWS
    gDataDir = conf.dataUri;
    gDataDir.normalizeSelf();
    gCacheDir = bx::getTempDir();
#elif BX_PLATFORM_IOS
    iosGetCacheDir(&gCacheDir);
    iosGetDataDir(&gDataDir);
    bx::FileInfo info;
    if (!bx::stat(gDataDir.cstr(), info)) {
        bx::make(gDataDir.cstr());
    }
#endif

    // Error handler
    if (!err::init(gAlloc)) {
        return false;
    }

    // Memory pool for MemoryBlock objects
    if (!gTee->memPool.create(MEM_POOL_BUCKET_SIZE, gAlloc))
        return false;

    if (!initMemoryPool(gAlloc, conf.pageSize*1024, conf.maxPagesPerPool))
        return false;

    // Random pools
    gTee->randomPoolInt = (int*)BX_ALLOC(gAlloc, sizeof(int)*RANDOM_NUMBER_POOL);
    gTee->randomPoolFloat = (float*)BX_ALLOC(gAlloc, sizeof(float)*RANDOM_NUMBER_POOL);
    if (!gTee->randomPoolInt || !gTee->randomPoolFloat)
        return false;
    restartRandom();    // fill random values

    // Initialize plugins system and enumerate plugins
    if (!initPluginSystem(conf.pluginPath.cstr(), gAlloc)) {
        TEE_ERROR("Engine init failed: PluginSystem failed");
        return false;
    }

    // IO
    PluginHandle ioPlugin = findPlugin(!conf.ioName.isEmpty() ? conf.ioName.cstr() : "DiskIO", PluginType::IoDriver);
    if (ioPlugin.isValid()) {
        gTee->ioDriver = (IoDriverDual*)initPlugin(ioPlugin, gAlloc);
        if (!gTee->ioDriver) {
            TEE_ERROR("Engine init failed: Could not find IO driver");
            return false;
        }

        // Initialize IO
        // If data path is chosen, set is as root path
        // If not, use the current directory as the root path
        const char* uri;
        if (!conf.dataUri.isEmpty()) {
            uri = conf.dataUri.cstr();
        } else {
            bx::FilePath curPath(bx::Dir::Current);
            uri = curPath.get();
        }

        const PluginDesc& desc = getPluginDesc(ioPlugin);
        BX_BEGINP("Initializing IO Driver: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version), TEE_VERSION_MINOR(desc.version));
        if (!gTee->ioDriver->blocking->init(gAlloc, uri, nullptr, nullptr, IoFlags::ExtractLZ4) ||
            !gTee->ioDriver->async->init(gAlloc, uri, nullptr, nullptr, IoFlags::ExtractLZ4))
        {
            BX_END_FATAL();
            TEE_ERROR("Engine init failed: Initializing IoDriver failed");
            return false;
        }
        BX_END_OK();
    }

    if (!gTee->ioDriver) {
        TEE_ERROR("Engine init failed: No IoDriver is detected");
        return false;
    }

    BX_BEGINP("Initializing Resource Library");
    if (!asset::init(BX_ENABLED(termite_DEV) ? AssetLibInitFlags::HotLoading : 0, gTee->ioDriver->async,
                     gAlloc, gTee->ioDriver->blocking))
    {
        TEE_ERROR("Core init failed: Creating default ResourceLib failed");
        return false;
    }
    BX_END_OK();

    // Renderer
    if (!conf.rendererName.isEmpty()) {
        PluginHandle rendererPlugin = findPlugin(conf.rendererName.cstr(), PluginType::Renderer);
        if (rendererPlugin.isValid()) {
            gTee->renderer = (RendererApi*)initPlugin(rendererPlugin, gAlloc);
            const PluginDesc& desc = getPluginDesc(rendererPlugin);
            BX_TRACE("Found Renderer: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version), TEE_VERSION_MINOR(desc.version));

            if (!platform) {
                TEE_ERROR("Core init failed: PlatformData is not provided for Renderer");
                return false;
            }
        }
    }

    // Graphics Device
    if (!conf.gfxName.isEmpty())    {
        PluginHandle gfxPlugin = findPlugin(conf.gfxName.cstr(), PluginType::GraphicsDriver);
        if (gfxPlugin.isValid()) {
            gTee->gfxDriver = (GfxDriver*)initPlugin(gfxPlugin, gAlloc);
        }

        if (!gTee->gfxDriver) {
            TEE_ERROR("Core init failed: Could not detect Graphics driver: %s", conf.gfxName.cstr());
            return false;
        }

        const PluginDesc& desc = getPluginDesc(gfxPlugin);
        BX_BEGINP("Initializing Graphics Driver: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version),
                  TEE_VERSION_MINOR(desc.version));
        if (platform)
            gTee->gfxDriver->setPlatformData(*platform);
        if (!gTee->gfxDriver->init(conf.gfxRenderApi, conf.gfxDeviceId, &gTee->gfxDriverEvents, gAlloc,
                                   conf.gfxTransientVbSize, conf.gfxTransientIbSize))
        {
            BX_END_FATAL();
            dumpGfxLog();
            TEE_ERROR("Core init failed: Could not initialize Graphics driver");
            return false;
        }
        BX_END_OK();
        dumpGfxLog();

        // Initialize Renderer with Gfx Driver
        if (gTee->renderer) {
            BX_BEGINP("Initializing Renderer");
            if (!gTee->renderer->init(gAlloc, gTee->gfxDriver)) {
                BX_END_FATAL();
                TEE_ERROR("Core init failed: Could not initialize Renderer");
                return false;
            }
            BX_END_OK();
        }

        // Init and Register graphics resource loaders
        gfx::initTextureLoader(gTee->gfxDriver, gAlloc);
        gfx::registerTextureToAssetLib();

        gfx::initModelLoader(gTee->gfxDriver, gAlloc);
        gfx::registerModelToAssetLib();

        gfx::initFontSystem(gAlloc, vec2(float(conf.refScreenWidth), float(conf.refScreenHeight)));
        gfx::registerFontToAssetLib();

        // VectorGraphics
        if (!gfx::initDebugDraw2D(gAlloc, gTee->gfxDriver)) {
            TEE_ERROR("Initializing Vector Graphics failed");
            return false;
        }

        // Debug graphics
        if (!gfx::initDebugDraw(gAlloc, gTee->gfxDriver)) {
            TEE_ERROR("Initializing Editor Draw failed");
            return false;
        }

        // Graphics Utilities
        if (!gfx::initGfxUtils(gTee->gfxDriver)) {
            TEE_ERROR("Initializing Graphics Utilities failed");
            return false;
        }

        // ImGui initialize
        if (!initImGui(IMGUI_VIEWID, gTee->gfxDriver, gAlloc, conf.keymap,
                       conf.uiIniFilename.cstr(), platform ? platform->nwh : nullptr)) {
            TEE_ERROR("Initializing ImGui failed");
            return false;
        }

        if (!gfx::initSpriteSystem(gTee->gfxDriver, gAlloc)) {
            TEE_ERROR("Initializing Sprite System failed");
            return false;
        }
        gfx::registerSpriteSheetToAssetLib();

        if (!gfx::initMaterialLib(gAlloc, gTee->gfxDriver)) {
            TEE_ERROR("Initializing material lib failed");
            return false;
        }
    }

    // Physics2D Driver
    if (!conf.phys2dName.isEmpty()) {
        PluginHandle phys2dPlugin = findPlugin(conf.phys2dName.cstr(), PluginType::Physics2dDriver);
        if (phys2dPlugin.isValid()) {
            gTee->phys2dDriver = (PhysDriver2D*)initPlugin(phys2dPlugin, gAlloc);
        }

        if (!gTee->phys2dDriver) {
            TEE_ERROR("Core init failed: Could not detect Physics driver: %s", conf.phys2dName.cstr());
            return false;
        }

        const PluginDesc& desc = getPluginDesc(phys2dPlugin);
        BX_BEGINP("Initializing Physics2D Driver: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version),
                  TEE_VERSION_MINOR(desc.version));
        if (!gTee->phys2dDriver->init(gAlloc, BX_ENABLED(termite_DEV) ? PhysFlags2D::EnableDebug : 0, NANOVG_VIEWID)) {
            BX_END_FATAL();
            TEE_ERROR("Core init failed: Could not initialize Physics2D driver");
            return false;
        }
        BX_END_OK();
    }

    // Sound device
    if (!conf.soundName.isEmpty()) {
        PluginHandle sndPlugin = findPlugin(conf.soundName.cstr(), PluginType::SimpleSoundDriver);
        if (sndPlugin.isValid()) {
            gTee->sndDriver = (SimpleSoundDriver*)initPlugin(sndPlugin, gAlloc);
        }

        if (!gTee->sndDriver) {
            TEE_ERROR("Core init failed: Could not detect Sound driver: %s", conf.soundName.cstr());
            return false;
        }

        const PluginDesc& desc = getPluginDesc(sndPlugin);
        BX_BEGINP("Initializing Sound Driver: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version), TEE_VERSION_MINOR(desc.version));
        if (!gTee->sndDriver->init(conf.audioFreq, conf.audioChannels, conf.audioBufferSize)) {
            BX_END_FATAL();
            TEE_ERROR("Core init failed: Could not initialize Sound driver");
            return false;
        }
        BX_END_OK();
    }

    // Job Dispatcher
    if ((conf.engineFlags & InitEngineFlags::EnableJobDispatcher) == InitEngineFlags::EnableJobDispatcher) {
        BX_BEGINP("Initializing Job Dispatcher");
        if (!initJobDispatcher(gAlloc, conf.maxSmallFibers, conf.smallFiberSize*1024, conf.maxBigFibers,
                              conf.bigFiberSize*1024,
                              (conf.engineFlags & InitEngineFlags::LockThreadsToCores) == InitEngineFlags::LockThreadsToCores))
        {
            TEE_ERROR("Core init failed: Job Dispatcher init failed");
            BX_END_FATAL();
            return false;
        }
        BX_END_OK();
        BX_TRACE("%d Worker threads spawned", getNumWorkerThreads());
    }

	// Component System
	BX_BEGINP("Initializing Component System");
	if (!ecs::init(gAlloc)) {
		TEE_ERROR("Core init failed: Could not initialize Component-System");
		BX_END_FATAL();
		return false;
	}
	BX_END_OK();

    BX_BEGINP("Initializing Event Dispatcher");
    if (!initEventDispatcher(gAlloc)) {
        TEE_ERROR("Core init fialed: Could not initialize Event Dispatcher");
        BX_END_FATAL();
        return false;
    }
    BX_END_OK();

#ifdef termite_SDL2
    BX_BEGINP("Initializing SDL2 utils");
    if (!sdl::init(gAlloc)) {
        TEE_ERROR("Core init failed: Could not initialize SDL2 utils");
        BX_END_FATAL();
        return false;
    }
    BX_END_OK();
#endif

#if termite_DEV
    BX_BEGINP("Initializing Command System");
    if (!cmd::init(conf.cmdHistorySize, gAlloc)) {
        TEE_ERROR("Core init failed: Could not initialize Command System");
        BX_END_FATAL();
        return false;
    }
    BX_END_OK();
#endif

#if RMT_ENABLED
    BX_BEGINP("Initializing Remotery");
    rmtSettings* rsettings = rmt_Settings();
    rsettings->malloc = remoteryMallocCallback;
    rsettings->free = remoteryFreeCallback;
    rsettings->realloc = remoteryReallocCallback;
#  if termite_DEV
    gTee->consoleCmds.create(64, 64, gAlloc);
    rsettings->input_handler = remoteryInputHandlerCallback;
#endif

    if (rmt_CreateGlobalInstance(&gTee->rmt) != RMT_ERROR_NONE) {
        BX_END_NONFATAL();
    }
    BX_END_OK();
#endif

#ifdef termite_CURL
    BX_BEGINP("Initializing Http Client");
    if (!http::init(gAlloc)) {
        TEE_ERROR("Core init failed: Could not initialize SDL2 utils");
        BX_END_FATAL();
        return false;
    }
    BX_END_OK();
#endif

    lang::registerToAssetLib();

    gTee->init = true;
    return true;
}

void shutdown(ShutdownCallback callback, void* userData)
{
    if (!gTee) {
        BX_ASSERT(false);
        return;
    }

#if termite_CURL
    BX_BEGINP("Shutting down Http Client");
    http::shutdown();
    BX_END_OK();
#endif

#if RMT_ENABLED
    BX_BEGINP("Shutting down Remotery");
    if (gTee->rmt)
        rmt_DestroyGlobalInstance(gTee->rmt);
    for (int i = 0; i < gTee->consoleCmds.getCount(); ++i) {
        ConsoleCommand* cmd = gTee->consoleCmds.itemPtr(i);
        cmd->~ConsoleCommand();
    }
    gTee->consoleCmds.destroy();
    BX_END_OK();
#endif

#if termite_DEV
    BX_BEGINP("Shutting down Command System");
    cmd::shutdown();
    BX_END_OK();
#endif

#ifdef termite_SDL2
    BX_BEGINP("Shutting down SDL2 utils");
    sdl::shutdown();
    BX_END_OK();
#endif

    BX_BEGINP("Shutting down Event Dispatcher");
    shutdownEventDispatcher();
    BX_END_OK();

	BX_BEGINP("Shutting down Component System");
	ecs::shutdown();
	BX_END_OK();

	BX_BEGINP("Shutting down Job Dispatcher");
    shutdownJobDispatcher();
	BX_END_OK();

    if (gTee->phys2dDriver) {
        BX_BEGINP("Shutting down Physics2D Driver");
        gTee->phys2dDriver->shutdown();
        gTee->phys2dDriver = nullptr;
        BX_END_OK();
    }

    BX_BEGINP("Shutting down Graphics Subsystems");
    gfx::destroyMaterialUniforms();
    gfx::shutdownMaterialLib();
    gfx::shutdownSpriteSystem();
	shutdownImGui();
    gfx::shutdownDebugDraw();
    gfx::shutdownDebugDraw2D();
    gfx::shutdownFontSystem();
    gfx::shutdownModelLoader();
    gfx::shutdownTextureLoader();
    gfx::shutdownGfxUtils();
    BX_END_OK();

    if (gTee->renderer) {
        BX_BEGINP("Shutting down Renderer");
        gTee->renderer->shutdown();
        gTee->renderer = nullptr;
        BX_END_OK();
    }

    if (gTee->gfxDriver) {
        BX_BEGINP("Shutting down Graphics Driver");
        gTee->gfxDriver->shutdown();
        gTee->gfxDriver = nullptr;
        BX_END_OK();
        dumpGfxLog();
    }

    if (gTee->sndDriver) {
        BX_BEGINP("Shutting down Sound Driver");
        gTee->sndDriver->shutdown();
        gTee->sndDriver = nullptr;
        BX_END_OK();
    }

    asset::shutdown();

    // User Shutdown happens before IO and memory stuff
    // In order for user to clean-up any memory or save stuff
    if (callback) {
        callback(userData);
    }

    if (gTee->ioDriver) {
        BX_BEGINP("Shutting down IO Driver");
        gTee->ioDriver->blocking->shutdown();
        gTee->ioDriver->async->shutdown();
        gTee->ioDriver = nullptr;
        BX_END_OK();
    }

    BX_BEGINP("Shutting down Plugin system");
    shutdownPluginSystem();
    BX_END_OK();

    if (gTee->gfxLogCache) {
        BX_FREE(gAlloc, gTee->gfxLogCache);
        gTee->gfxLogCache = nullptr;
        gTee->numGfxLogCache = 0;
    }

    BX_BEGINP("Destroying Memory pools");
    gTee->memPool.destroy();
    shutdownMemoryPool();
    BX_END_OK();

    if (gTee->randomPoolFloat)
        BX_FREE(gAlloc, gTee->randomPoolFloat);
    if (gTee->randomPoolInt)
        BX_FREE(gAlloc, gTee->randomPoolInt);

    err::shutdown();
    BX_DELETE(gAlloc, gTee);
    gTee = nullptr;

    if (gTraceAlloc) {
        const bx::TraceAllocator::TraceItem* trace = gTraceAlloc->getFirstLeak();
        BX_WARN("Leaks found: (Total %u bytes (%u kb))", gTraceAlloc->getAllocatedSize(), gTraceAlloc->getAllocatedSize()/1024);
        if (trace) {
            while (trace) {
                BX_TRACE("\t%u bytes: %s (%d)", (uint32_t)trace->size, trace->filename, trace->line);
                trace = gTraceAlloc->getNextLeak();
            }
        }

        BX_DELETE(gPrevAlloc, gTraceAlloc);
        gAlloc = gPrevAlloc;
    }

#if defined(_DEBUG)
    stb_leakcheck_dumpmem();
#endif
}

static double calcAvgFrameTime(const FrameData& fd)
{
    double sum = 0;
    for (int i = 0; i < BX_COUNTOF(fd.frameTimes); i++) {
        sum += fd.frameTimes[i];
    }
    sum /= double(BX_COUNTOF(fd.frameTimes));
    return sum;
}

void doFrame()
{
    rmt_BeginCPUSample(DoFrame, 0);
    gTee->tempAlloc.free();

    FrameData& fd = gTee->frameData;
    if (fd.frame == 0)
        fd.lastFrameTimePt = TClock::now();

    TClockTimePt frameTimePt = TClock::now();
    std::chrono::duration<double> dt_fp = frameTimePt - fd.lastFrameTimePt;
    double dt = gTee->timeMultiplier * dt_fp.count();
    float fdt = float(dt);

    if (gTee->gfxDriver) {
        ImGui::GetIO().DeltaTime = float(dt_fp.count());
        ImGui::NewFrame();
        ImGuizmo::BeginFrame();
    }

    rmt_BeginCPUSample(Game_Update, 0);
    if (gTee->updateFn)
        gTee->updateFn(fdt);
    rmt_EndCPUSample(); // Game_Update

    runEventDispatcher(fdt);

    rmt_BeginCPUSample(ImGui_Render, 0);
    if (gTee->gfxDriver) {
        ImGui::Render();
        ImGui::GetIO().MouseWheel = 0;
    }
    rmt_EndCPUSample(); // ImGuiRender

    if (gTee->renderer)
        gTee->renderer->render(nullptr);

    rmt_BeginCPUSample(Async_Loop, 0);
    if (gTee->ioDriver->async)
        gTee->ioDriver->async->runAsyncLoop();
    rmt_EndCPUSample(); // Async_Loop

    rmt_BeginCPUSample(Gfx_DrawFrame, 0);
    if (gTee->gfxDriver)
        gTee->frameData.renderFrame = gTee->gfxDriver->frame();
    rmt_EndCPUSample(); // Gfx_DrawFrame

#ifdef termite_CURL
    http::update();     // Async Request process
#endif

    fd.frame++;
    fd.elapsedTime += dt;
    fd.frameTime = dt;
    fd.lastFrameTimePt = frameTimePt;
    int frameTimeIter = fd.frame % BX_COUNTOF(fd.frameTimes);
    fd.frameTimes[frameTimeIter] = dt;
    fd.avgFrameTime = calcAvgFrameTime(fd);
    double fpsTime = fd.elapsedTime - fd.fpsTime;
    if (frameTimeIter == 0 && fpsTime != 0) {
        fd.fps = BX_COUNTOF(fd.frameTimes) / fpsTime;
        fd.fpsTime = fd.elapsedTime;
    }
    rmt_EndCPUSample(); // DoFrame
}

void pause()
{
    gTee->timeMultiplier = 0;
}

void resume()
{
    gTee->timeMultiplier = 1.0;
    gTee->frameData.lastFrameTimePt = TClock::now();
}

bool isPaused()
{
    return gTee->timeMultiplier == 0;
}

void resetTempAlloc()
{
    gTee->tempAlloc.free();
}

void resetBackbuffer(uint16_t width, uint16_t height)
{
    if (gTee->gfxDriver)
        gTee->gfxDriver->reset(width, height, gTee->conf.gfxDriverFlags);
    gTee->conf.gfxWidth = width;
    gTee->conf.gfxHeight = height;

    ImGuiIO& io = ImGui::GetIO();
    io.DisplaySize = ImVec2(float(width), float(height));
}

double getFrameTime()
{
    return gTee->frameData.frameTime;
}

double getElapsedTime()
{
    return gTee->frameData.elapsedTime;
}

double getFps()
{
    return gTee->frameData.fps;
}

double getSmoothFrameTime()
{
    return gTee->frameData.avgFrameTime;
}

uint64_t getFrameIndex()
{
    return gTee->frameData.frame;
}

uint32_t getRenderFrameIndex()
{
    return gTee->frameData.renderFrame;
}

MemoryBlock* createMemoryBlock(uint32_t size, bx::AllocatorI* alloc)
{
    if (size > 0) {
        ScopedLock  l(gTee->memPoolLock);
        HeapMemoryImpl* mem = gTee->memPool.newInstance();
        if (!mem)
            return nullptr;
        if (!alloc)
            alloc = gAlloc;

        mem->m.data = (uint8_t*)BX_ALLOC(alloc, size);

        if (mem->m.data != nullptr) {
            mem->m.size = size;
            mem->alloc = alloc;
            return (MemoryBlock*)mem;
        } else {
            gTee->memPool.deleteInstance(mem);
            return nullptr;
        }
    } else {
        return nullptr;
    }
}

MemoryBlock* refMemoryBlockPtr(const void* data, uint32_t size)
{
    ScopedLock l(gTee->memPoolLock);
    HeapMemoryImpl* mem = gTee->memPool.newInstance();
    if (!mem)
        return nullptr;
    mem->m.data = (uint8_t*)const_cast<void*>(data);
    mem->m.size = size;

    return (MemoryBlock*)mem;
}

MemoryBlock* copyMemoryBlock(const void* data, uint32_t size, bx::AllocatorI* alloc)
{
    ScopedLock l(gTee->memPoolLock);
    HeapMemoryImpl* mem = gTee->memPool.newInstance();
    if (!mem)
        return nullptr;
    if (!alloc)
        alloc = gAlloc;
    mem->m.data = (uint8_t*)BX_ALLOC(alloc, size);
    if (!mem->m.data) {
        gTee->memPool.deleteInstance(mem);
        return nullptr;
    }
    memcpy(mem->m.data, data, size);
    mem->m.size = size;
    mem->alloc = alloc;

    return (MemoryBlock*)mem;
}

MemoryBlock* refMemoryBlock(MemoryBlock* mem)
{
    HeapMemoryImpl* m = (HeapMemoryImpl*)mem;
    bx::atomicFetchAndAdd(&m->refcount, 1);
    return mem;
}

void releaseMemoryBlock(MemoryBlock* mem)
{
    HeapMemoryImpl* m = (HeapMemoryImpl*)mem;
    ScopedLock l(gTee->memPoolLock);
    if (bx::atomicDec(&m->refcount) == 0) {
        if (m->alloc) {
            BX_FREE(m->alloc, m->m.data);
            m->m.data = nullptr;
            m->m.size = 0;
        }

        gTee->memPool.deleteInstance(m);
    }
}

MemoryBlock* readTextFile(const char* absFilepath)
{
    bx::FileReader file;
    bx::Error err;
    if (!file.open(absFilepath, &err))
        return nullptr;
    uint32_t size = (uint32_t)file.seek(0, bx::Whence::End);

    MemoryBlock* mem = createMemoryBlock(size + 1, gAlloc);
    if (!mem) {
        file.close();
        return nullptr;
    }

    file.seek(0, bx::Whence::Begin);
    file.read(mem->data, size, &err);
    ((char*)mem->data)[size] = 0;
    file.close();

    return mem;
}

MemoryBlock* readBinaryFile(const char* absFilepath)
{
    bx::FileReader file;
    bx::Error err;
    if (!file.open(absFilepath, &err))
        return nullptr;
    uint32_t size = (uint32_t)file.seek(0, bx::Whence::End);
    if (size == 0) {
        file.close();
        return nullptr;
    }

    MemoryBlock* mem = createMemoryBlock(size, gAlloc);
    if (!mem) {
        file.close();
        return nullptr;
    }

    file.seek(0, bx::Whence::Begin);
    file.read(mem->data, size, &err);
    file.close();

    return mem;
}

bool saveBinaryFile(const char* absFilepath, const MemoryBlock* mem)
{
    bx::FileWriter file;
    bx::Error err;
    if (mem->size == 0 || !file.open(absFilepath, false, &err)) {
        return false;
    }

    int wb = file.write(mem->data, mem->size, &err);
    file.close();
    return wb == mem->size ? true : false;
}

MemoryBlock* encryptMemoryAES128(const MemoryBlock* mem, bx::AllocatorI* alloc, const uint8_t* key, const uint8_t* iv)
{
    BX_ASSERT(mem);
    if (key == nullptr)
        key = kAESKey;
    if (iv == nullptr)
        iv = kAESIv;
    if (alloc == nullptr)
        alloc = gAlloc;

    EncodeHeader header;
    header.sign = T_ENC_SIGN;
    header.version = T_ENC_VERSION;

    // Compress LZ4
    int maxSize = BX_ALIGN_16(LZ4_compressBound(mem->size));
    void* compressedBuff = BX_ALLOC(alloc, maxSize);
    if (!compressedBuff)
        return nullptr;
    int compressSize = LZ4_compress_default((const char*)mem->data, (char*)compressedBuff, mem->size, maxSize);
    int alignedCompressSize = BX_ALIGN_16(compressSize);
    BX_ASSERT(alignedCompressSize <= maxSize);
    bx::memSet((uint8_t*)compressedBuff + compressSize, 0x00, alignedCompressSize - compressSize);

    // AES Encode
    MemoryBlock* encMem = createMemoryBlock(alignedCompressSize + sizeof(header), alloc);
    if (encMem) {
        AES_CBC_encrypt_buffer((uint8_t*)encMem->data + sizeof(header), (uint8_t*)compressedBuff, alignedCompressSize, key, iv);

        // finalize header and slap it at the begining of the output buffer
        header.decodeSize = compressSize;
        header.uncompSize = (int)mem->size;
        *((EncodeHeader*)encMem->data) = header;
    }

    BX_FREE(alloc, compressedBuff);
    return encMem;
}

MemoryBlock* decryptMemoryAES128(const MemoryBlock* mem, bx::AllocatorI* alloc, const uint8_t* key, const uint8_t* iv)
{
    BX_ASSERT(mem);
    if (key == nullptr)
        key = kAESKey;
    if (iv == nullptr)
        iv = kAESIv;
    if (alloc == nullptr)
        alloc = gAlloc;

    // AES Decode
    const EncodeHeader header = *((const EncodeHeader*)mem->data);
    if (header.sign != T_ENC_SIGN ||
        header.version != T_ENC_VERSION)
    {
        return nullptr;
    }

    uint8_t* encBuff = (uint8_t*)mem->data + sizeof(header);
    uint32_t encSize = mem->size - sizeof(header);
    BX_ASSERT(encSize % 16 == 0);

    void* decBuff = BX_ALLOC(alloc, encSize);
    if (!decBuff)
        return nullptr;
    AES_CBC_decrypt_buffer((uint8_t*)decBuff, encBuff, encSize, key, iv);

    // Uncompress LZ4
    MemoryBlock* rmem = createMemoryBlock(header.uncompSize, alloc);
    if (rmem)
        LZ4_decompress_safe((const char*)decBuff, (char*)rmem->data, header.decodeSize, header.uncompSize);

    BX_FREE(alloc, decBuff);
    return rmem;
}

void cipherXOR(uint8_t* outputBuff, const uint8_t* inputBuff, size_t buffSize, const uint8_t* key, size_t keySize)
{
    BX_ASSERT(buffSize > 0);
    BX_ASSERT(keySize > 0);
    for (size_t i = 0; i < buffSize; i++) {
        outputBuff[i] = inputBuff[i] ^ key[i % keySize];
    }
}

void restartRandom()
{
    std::uniform_int_distribution<int> idist(0, INT_MAX);
    int* randomInt = gTee->randomPoolInt;
    for (int i = 0; i < RANDOM_NUMBER_POOL; i++) {
        randomInt[i] = idist(gTee->randEngine);
    }

    std::uniform_real_distribution<float> fdist(0, 1.0f);
    float* randomFloat = gTee->randomPoolFloat;
    for (int i = 0; i < RANDOM_NUMBER_POOL; i++) {
        randomFloat[i] = fdist(gTee->randEngine);
    }

    gTee->randomFloatOffset = gTee->randomIntOffset = 0;
}

float getRandomFloatUniform(float a, float b)
{
    BX_ASSERT(a <= b);
    int off = gTee->randomFloatOffset;
    float r = (gTee->randomPoolFloat[off]*(b - a)) + a;
    bx::atomicExchange<int32_t>(&gTee->randomFloatOffset, (off + 1) % RANDOM_NUMBER_POOL);
    return r;
}

int getRandomIntUniform(int a, int b)
{
    BX_ASSERT(a <= b);
    int off = gTee->randomIntOffset;
    int r = (gTee->randomPoolInt[off] % (b - a + 1)) + a;
    bx::atomicExchange<int32_t>(&gTee->randomIntOffset, (off + 1) % RANDOM_NUMBER_POOL);
    return r;
}

float getRandomFloatNormal(float mean, float sigma)
{
    std::normal_distribution<float> dist(mean, sigma);
    return dist(gTee->randEngine);
}

void inputSendChars(const char* chars)
{
	ImGuiIO& io = ImGui::GetIO();
    io.AddInputCharactersUTF8(chars);
}

void inputSendKeys(const bool keysDown[512], bool shift, bool alt, bool ctrl)
{
	ImGuiIO& io = ImGui::GetIO();
	memcpy(io.KeysDown, keysDown, 512*sizeof(bool));
	io.KeyShift = shift;
	io.KeyAlt = alt;
	io.KeyCtrl = ctrl;
}

void inputSendMouse(float mousePos[2], int mouseButtons[3], float mouseWheel)
{
	ImGuiIO& io = ImGui::GetIO();
	io.MousePos = ImVec2(mousePos[0], mousePos[1]);

	io.MouseDown[0] = mouseButtons[0] ? true : false;
	io.MouseDown[1] = mouseButtons[1] ? true : false;
	io.MouseDown[2] = mouseButtons[2] ? true : false;

	io.MouseWheel += mouseWheel;
}

GfxDriver* getGfxDriver()
{
    return gTee->gfxDriver;
}

IoDriver* getBlockingIoDriver() TEE_THREAD_SAFE
{
    return gTee->ioDriver->blocking;
}

IoDriver* getAsyncIoDriver() TEE_THREAD_SAFE
{
    return gTee->ioDriver->async;
}

RendererApi* getRenderer() TEE_THREAD_SAFE
{
    return gTee->renderer;
}

SimpleSoundDriver* getSoundDriver() TEE_THREAD_SAFE
{
    return gTee->sndDriver;
}

PhysDriver2D* getPhys2dDriver() TEE_THREAD_SAFE
{
    return gTee->phys2dDriver;
}

uint32_t getEngineVersion() TEE_THREAD_SAFE
{
    return TEE_MAKE_VERSION(0, 1);
}

bx::AllocatorI* getHeapAlloc() TEE_THREAD_SAFE
{
    return gAlloc;
}

bx::AllocatorI* getTempAlloc() TEE_THREAD_SAFE
{
    return &gTee->tempAlloc;
}

const Config& getConfig() TEE_THREAD_SAFE
{
    return gTee->conf;
}

Config* getMutableConfig() TEE_THREAD_SAFE
{
    return &gTee->conf;
}

TEE_API void setCacheDir(const char* dir)
{
    bx::FileInfo info;
    bx::stat(dir, info);
    if (info.m_type == bx::FileInfo::Directory) {
        gCacheDir = dir;
    } else {
        BX_WARN("setCacheDir: '%s' is not a directory", dir);
    }
}

const char* getCacheDir() TEE_THREAD_SAFE
{
    return gCacheDir.cstr();
}

const char* getDataDir() TEE_THREAD_SAFE
{
    return gDataDir.cstr();
}

const char* getPackageVersion() TEE_THREAD_SAFE
{
    return gPackageVersion.cstr();
}

void dumpGfxLog() TEE_THREAD_SAFE
{
    if (gTee->gfxLogCache) {
        for (int i = 0, c = gTee->numGfxLogCache; i < c; i++) {
            const LogCache& l = gTee->gfxLogCache[i];
            debug::print(__FILE__, __LINE__, l.type, l.text);
        }

        BX_FREE(gAlloc, gTee->gfxLogCache);
        gTee->gfxLogCache = nullptr;
        gTee->numGfxLogCache = 0;
    }
}

bool needGfxReset() TEE_THREAD_SAFE
{
    return gTee->gfxReset;
}

void shutdownGraphics()
{
    // Unload all graphics resources
    asset::unloadAssets("texture");

    // Unload subsystems
    gfx::shutdownSpriteSystemGraphics();
    shutdownImGui();
    gfx::shutdownDebugDraw();
    gfx::shutdownDebugDraw2D();
    gfx::shutdownFontSystemGraphics();
    gfx::shutdownModelLoader();
    gfx::shutdownTextureLoader();
    gfx::shutdownGfxUtils();
    gfx::destroyMaterialUniforms();

    if (gTee->phys2dDriver) {
        gTee->phys2dDriver->shutdownGraphicsObjects();
    }

    // Shutdown driver
    if (gTee->gfxDriver) {
        gTee->gfxDriver->shutdown();
        gTee->gfxDriver = nullptr;
        dumpGfxLog();
    }
}

bool resetGraphics(const GfxPlatformData* platform)
{
    const Config& conf = gTee->conf;

    PluginHandle gfxPlugin = findPlugin(conf.gfxName.cstr(), PluginType::GraphicsDriver);
    if (gfxPlugin.isValid()) {
        gTee->gfxDriver = (GfxDriver*)initPlugin(gfxPlugin, gAlloc);
    }

    if (!gTee->gfxDriver) {
        TEE_ERROR("Core init failed: Could not detect Graphics driver: %s", conf.gfxName.cstr());
        return false;
    }

    const PluginDesc& desc = getPluginDesc(gfxPlugin);
    BX_BEGINP("Initializing Graphics Driver: %s v%d.%d", desc.name, TEE_VERSION_MAJOR(desc.version),
              TEE_VERSION_MINOR(desc.version));
    if (platform)
        gTee->gfxDriver->setPlatformData(*platform);
    if (!gTee->gfxDriver->init(conf.gfxRenderApi, conf.gfxDeviceId, &gTee->gfxDriverEvents, gAlloc,
                               conf.gfxTransientVbSize, conf.gfxTransientIbSize))
    {
        BX_END_FATAL();
        dumpGfxLog();
        TEE_ERROR("Core init failed: Could not initialize Graphics driver");
        return false;
    }
    BX_END_OK();
    dumpGfxLog();

    // Initialize Renderer with Gfx Driver
    if (gTee->renderer) {
        BX_BEGINP("Initializing Renderer");
        if (!gTee->renderer->init(gAlloc, gTee->gfxDriver)) {
            BX_END_FATAL();
            TEE_ERROR("Core init failed: Could not initialize Renderer");
            return false;
        }
        BX_END_OK();
    }

    // Init and Register graphics resource loaders
    gfx::initTextureLoader(gTee->gfxDriver, gAlloc);
    gfx::registerTextureToAssetLib();

    gfx::initModelLoader(gTee->gfxDriver, gAlloc);
    gfx::registerModelToAssetLib();

    gfx::initFontSystemGraphics();

    // VectorGraphics
    if (!gfx::initDebugDraw2D(gAlloc, gTee->gfxDriver)) {
        TEE_ERROR("Initializing Vector Graphics failed");
        return false;
    }

    // Debug graphics
    if (!gfx::initDebugDraw(gAlloc, gTee->gfxDriver)) {
        TEE_ERROR("Initializing Editor Draw failed");
        return false;
    }

    // Graphics Utilities
    if (!gfx::initGfxUtils(gTee->gfxDriver)) {
        TEE_ERROR("Initializing Graphics Utilities failed");
        return false;
    }

    // ImGui initialize
    if (!initImGui(IMGUI_VIEWID, gTee->gfxDriver, gAlloc, conf.keymap, conf.uiIniFilename.cstr(),
                   platform ? platform->nwh : nullptr))
    {
        TEE_ERROR("Initializing ImGui failed");
        return false;
    }

    if (!gfx::initSpriteSystemGraphics(gTee->gfxDriver)) {
        TEE_ERROR("Initializing Sprite System failed");
        return false;
    }

    if (gTee->phys2dDriver) {
        gTee->phys2dDriver->initGraphicsObjects();
    }

    if (!gfx::createMaterialUniforms(gTee->gfxDriver)) {
        TEE_ERROR("Initializing material uniforms failed");
        return false;
    }

    // Reload resources
    asset::reloadAssets("texture");

    gTee->gfxReset = false;
    return true;
}

void registerConsoleCommand(const char* name, std::function<void(int, const char**)> callback)
{
#if termite_DEV && RMT_ENABLED
    BX_ASSERT(gTee);
    ConsoleCommand* cmd = new(gTee->consoleCmds.push()) ConsoleCommand;
    cmd->cmdHash = tinystl::hash_string(name, strlen(name));
    cmd->callback = callback;
#endif
}

const HardwareInfo& getHardwareInfo()
{
    return gHwInfo;
}

bool hasHardwareNavKey()
{
    return gHasHardwareKey;
}

void GfxDriverEvents::onFatal(GfxFatalType::Enum type, const char* str)
{
    char strTrimed[LOG_STRING_SIZE];
    bx::strCopy(strTrimed, sizeof(strTrimed), str);
    strTrimed[strlen(strTrimed) - 1] = 0;

    if (gTee->numGfxLogCache < 1000) {
        m_lock.lock();
        gTee->gfxLogCache = (LogCache*)BX_REALLOC(gAlloc, gTee->gfxLogCache, sizeof(LogCache) * (++gTee->numGfxLogCache));
        gTee->gfxLogCache[gTee->numGfxLogCache-1].type = LogType::Fatal;
        strcpy(gTee->gfxLogCache[gTee->numGfxLogCache-1].text, strTrimed);
        m_lock.unlock();
    }
}

void GfxDriverEvents::onTraceVargs(const char* filepath, int line, const char* format, va_list argList)
{
    char text[LOG_STRING_SIZE];
    vsnprintf(text, sizeof(text), format, argList);
    text[strlen(text) - 1] = 0;
    if (gTee->numGfxLogCache < 1000) {
        m_lock.lock();
        gTee->gfxLogCache = (LogCache*)BX_REALLOC(gAlloc, gTee->gfxLogCache, sizeof(LogCache) * (++gTee->numGfxLogCache));
        gTee->gfxLogCache[gTee->numGfxLogCache-1].type = LogType::Verbose;
        strcpy(gTee->gfxLogCache[gTee->numGfxLogCache-1].text, text);
        m_lock.unlock();
    }

}

} // namespace tee


text:
package br.com.caelum.pm73.dominio;

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

@Entity
public class Usuario {

	@Id @GeneratedValue
	private int id;
	private String nome;
	private String email;

	protected Usuario() {}

	public Usuario(String nome, String email) {
		this.nome = nome;
		this.email = email;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return nome;
	}

	public String getEmail() {
		return email;
	}

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

	public int getId() {
		return id;
	}

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

}


text:
 <?php
    $field = get_field_object('sign_off_level');
    $field_file = get_field_object('upload_content');

    $value = get_field('sign_off_level');
    $label = $field['choices'][ $value ];
    $color = get_color($value,false);

    $field_design = get_field_object('sign_off_level_design');
    $field_design_file = get_field_object('upload_content_design');

    $value_design = get_field('sign_off_level_design');
    $label_design = $field['choices'][$value_design];
    $color_design = get_color($value_design,false);
 ?>


text:
#ifndef DIREGIST_H
#define DIREGIST_H

#include "dcmtk/config/osconfig.h"

#include "dcmtk/dcmimgle/diregbas.h"

#include "dcmtk/dcmimage/dicdefin.h"

/*---------------------*
 *  class declaration  *
 *---------------------*/

/** Class to register color support to dcmimgle library
 */
class DCMTK_DCMIMAGE_EXPORT DiRegister
  : public DiRegisterBase
{

 public:

    /** constructor
     */
    DiRegister();

    /** destructor
     */
    virtual ~DiRegister();

    /** create color image representation
     *
     ** @param  docu    pointer to dataset (encapsulated)
     *  @param  status  image status
     *  @param  photo   photometric interpretation
     *
     ** @return pointer to new DiImage object (NULL if an error occurred)
     */
    virtual DiImage *createImage(const DiDocument *docu,
                                 const EI_Status status,
                                 const EP_Interpretation photo);

    /** create monochrome pixel data from color image
     *
     ** @param  image  pointer to color image
     *  @param  red    coefficient by which the red component is weighted
     *  @param  green  coefficient by which the green component is weighted
     *  @param  blue   coefficient by which the blue component is weighted
     *
     ** @return pointer to new DiImage object (NULL if an error occurred)
     */
    virtual DiMonoPixel *createMonoImageData(const DiColorImage *image,
                                             const double red,
                                             const double green,
                                             const double blue);
};

/*------------------*
 *  initialization  *
 *------------------*/

static DiRegister Init_dcmimage_Module;        // registration pointer is initialized in class constructor

#endif


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpDX;
using SharpDX.Mathematics.Interop;
using Fusion.Mathematics;

namespace Fusion {
	internal static class SharpDXHelper {

		static public RawVector3 Convert( Vector3 v )
		{
			return new RawVector3{ X = v.X, Y = v.Y, Z = v.Z };
		}

		static public RawColorBGRA Convert( Color v )
		{
			return new RawColorBGRA{ R = v.R, G = v.G, B = v.B, A = v.A };
		}

		static public RawColor4 Convert( Color4 v )
		{
			return new RawColor4{ R = v.Red, G = v.Green, B = v.Blue, A = v.Alpha };
		}

		static public RawInt4 Convert( Int4 v )
		{
			return new RawInt4{ X = v.X, Y = v.Y, Z = v.Z, W = v.W };
		}

		static public RawViewport Convert( Viewport v )
		{
			return new RawViewport{ X = v.X, Y = v.Y, Width = v.Width, Height = v.Height, MinDepth = v.MinDepth, MaxDepth = v.MaxDepth };
		}

		static public RawViewportF	Convert( ViewportF v )
		{
			return new RawViewportF { X = v.X, Y = v.Y, Width = v.Width, Height = v.Height, MinDepth = v.MinDepth, MaxDepth = v.MaxDepth };
		}

        static public SharpDX.X3DAudio.Listener ToListener(this Audio.AudioListener listener)
        {
            // Pulling out Vector properties for efficiency.
            var pos = listener.Position;
            var vel = listener.Velocity;
            var forward = listener.Forward;
            var up = listener.Up;

            // From MSDN:
            //  X3DAudio uses a left-handed Cartesian coordinate system,
            //  with values on the x-axis increasing from left to right, on the y-axis from bottom to top,
            //  and on the z-axis from near to far.
            //  Azimuths are measured clockwise from a given reference direction.
            //
            // From MSDN:
            //  The XNA Framework uses a right-handed coordinate system,
            //  with the positive z-axis pointing toward the observer when the positive x-axis is pointing to the right,
            //  and the positive y-axis is pointing up.
            //
            // Programmer Notes:
            //  According to this description the z-axis (forward vector) is inverted between these two coordinate systems.
            //  Therefore, we need to negate the z component of any position/velocity values, and negate any forward vectors.

            forward *= -1.0f;
            pos.Z *= -1.0f;
            vel.Z *= -1.0f;

            return new SharpDX.X3DAudio.Listener()
            {
                Position	=	Convert( pos ),
                Velocity	=	Convert( vel ),
                OrientFront =	Convert( forward ),
                OrientTop	=	Convert( up ),
            };
        }

		/// <summary>
		///
		/// </summary>
		/// <param name="curve"></param>
		/// <returns></returns>
		public static SharpDX.X3DAudio.CurvePoint[] Convert ( Audio.CurvePoint[] curve )
		{
			if (curve==null) {
				return null;
			}

			return curve
				.Select( c => new SharpDX.X3DAudio.CurvePoint{ Distance = c.Distance, DspSetting = c.DspSetting } )
				.ToArray();
		}

		/// <summary>
		///
		/// </summary>
		/// <param name="curve"></param>
		/// <returns></returns>
		public static Audio.CurvePoint[] Convert ( SharpDX.X3DAudio.CurvePoint[] curve )
		{
			if (curve==null) {
				return null;
			}

			return curve
				.Select( c => new Audio.CurvePoint{ Distance = c.Distance, DspSetting = c.DspSetting } )
				.ToArray();
		}
	}
}


text:
require 'rails_helper'

RSpec.describe Review, type: :model do
  let(:review) { build(:review) }

  it 'belongs_to a subject' do
    expect(review).to belong_to(:subject)
  end

  it 'has_many tokens' do
    expect(review).to have_many(:tokens)
  end

  describe 'validations' do
    it 'is valid' do
      expect(review).to be_valid
    end

    it 'requires an author_email' do
      review.author_email = nil
      expect(review).not_to be_valid
    end

    it 'requires an @ in the author_email' do
      review.author_email = 'bad'
      expect(review).not_to be_valid
    end

    it 'requires an author_name' do
      review.author_name = nil
      expect(review).not_to be_valid
    end

    it 'requires a subject' do
      review.subject = nil
      expect(review).not_to be_valid
    end

    it 'requires the subject to be a participant' do
      review.subject.participant = false
      expect(review).not_to be_valid
    end

    it 'restricts status to the whitelist' do
      review.status = 'garbage'
      expect(review).not_to be_valid
    end

    it 'is valid if fields are empty and status is not submitted' do
      review.rating_2 = nil
      review.status = :started
      expect(review).to be_valid
    end

    it 'is invalid if fields are empty and status is submitted' do
      review.rating_2 = nil
      review.status = :submitted
      expect(review).not_to be_valid
    end
  end

  describe 'status' do
    it 'is "no response" initially' do
      expect(review.status).to eql(:no_response)
    end
  end

  describe 'invitation message' do
    it 'has a default value' do
      expect(review.invitation_message).to match(/give feedback about my work/)
    end
  end

  it 'is remindable if the status is no_response, accepted, or started' do
    %i[ no_response accepted started ].each do |status|
      review.status = status
      expect(review).to be_remindable
    end
  end

  it 'is not remindable if the status is declined or submitted' do
    %i[ declined submitted ].each do |status|
      review.status = status
      expect(review).not_to be_remindable
    end
  end

  it 'is complete if the status is submitted' do
    review.status = :submitted
    expect(review).to be_complete
  end

  it 'is not complete if the status is not submitted' do
    %i[ no_response declined accepted started ].each do |status|
      review.status = status
      expect(review).not_to be_complete
    end
  end

  it 'delegates author_name to the author if possible' do
    author = create(:user, name: 'Robert Roberts')
    review = create(:review, author: author, author_name: 'bob')
    expect(review.author_name).to eql('Robert Roberts')
  end

  it 'uses its own author_name if delegation is not possible' do
    review = build(:review, author_name: 'bob')
    expect(review.author_name).to eql('bob')
  end

  it 'normalises author_email on assignment' do
    subject.author_email = 'USER@Example.com'
    expect(subject.author_email).to eql('user@example.com')
  end
end


text:
set(CMAKE_DEPENDS_LANGUAGES
  "CXX"
  )
# The set of files for implicit dependencies of each language:
set(CMAKE_DEPENDS_CHECK_CXX
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/apps/visualisation/opencv_visualisation.cpp" "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/apps/visualisation/CMakeFiles/opencv_visualisation.dir/opencv_visualisation.cpp.o"
  )
set(CMAKE_CXX_COMPILER_ID "Clang")

# Preprocessor definitions for this target.
set(CMAKE_TARGET_DEFINITIONS_CXX
  "__OPENCV_BUILD=1"
  )

# The include file search paths:
set(CMAKE_CXX_TARGET_INCLUDE_PATH
  "Accelerate"
  "3rdparty/ippicv/ippicv_osx/include"
  "."
  "apps/visualisation/PRIVATE"
  "apps/visualisation"
  "include/opencv"
  "modules/core/include"
  "modules/highgui/include"
  "modules/imgproc/include"
  "modules/imgcodecs/include"
  "modules/videoio/include"
  )

# Targets to which this target links.
set(CMAKE_TARGET_LINKED_INFO_FILES
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/modules/highgui/CMakeFiles/opencv_highgui.dir/DependInfo.cmake"
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/modules/videoio/CMakeFiles/opencv_videoio.dir/DependInfo.cmake"
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/DependInfo.cmake"
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/modules/imgproc/CMakeFiles/opencv_imgproc.dir/DependInfo.cmake"
  "/Users/jesusgarciamanday/Documents/Master/TFM/library/opencv-3.2.0/modules/core/CMakeFiles/opencv_core.dir/DependInfo.cmake"
  )

# Fortran module output directory.
set(CMAKE_Fortran_TARGET_MODULE_DIR "")


text:
package com.laytonsmith.core.compiler;

import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The alias compiler takes alias definitions and compiles them down into alias definitions.
 */
public class AliasCompiler {

	public static void main(String [] args) throws Exception {
		List<AliasToken> list = new AliasLexer("/c /* = */ = /** hi */ code", null).parse();
		System.out.println(list);
	}

	public static List<AliasToken> lex(String script, File file) throws ConfigCompileException{
		return new AliasLexer(script, file).parse();
	}

	private static class AliasLexer {
		private final String script;
		private final File file;
		private List<AliasToken> tokens;

		private StringBuilder buf = new StringBuilder();
		private Target t;

		private boolean pastLabel;
		private boolean pastDefinitionStart;
		private boolean inVariable;
		private boolean inQuote;
		private boolean inSingleString;
		private boolean inDoubleString;
		private boolean inOptionalVariable;
		private boolean inAliasCode;
		private boolean pastMultiline;
		private boolean inMultiline;
		private boolean isNewStyleMultiline;
		private boolean inComment;
		private boolean inLineComment;
		private boolean inMultilineComment;
		private boolean inDocBlockComment;

		public AliasLexer(String script, File file){
			if((int)script.charAt(0) == 65279){
				// Remove the UTF-8 Byte Order Mark, if present.
				script = script.substring(1);
			}
			script = script.replaceAll("\r\n", "\n");
			script = script + "\n";
			this.script = script;
			this.file = file;
		}

		public List<AliasToken> parse() throws ConfigCompileException{
			if(tokens == null){
				doParse();
			}
			return tokens;
		}

		private void doParse() throws ConfigCompileException {
			tokens = new ArrayList<>();
			int line = 1;
			int col = 0;
			Target singleQuoteStart = Target.UNKNOWN;
			Target doubleQuoteStart = Target.UNKNOWN;
			Target multilineCommentStart = Target.UNKNOWN;
			Target optionalVariableStart = Target.UNKNOWN;
			for(int i = 0; i < script.length(); i++){
				// Need up to a 3 lookahead
				col++;
				Character c = script.charAt(i);
				Character c2 = null;
				Character c3 = null;
				Character c4 = null;
				if (i < script.length() - 1) {
					c2 = script.charAt(i + 1);
				}
				if (i < script.length() - 2) {
					c3 = script.charAt(i + 2);
				}
				if (i < script.length() - 3) {
					c4 = script.charAt(i + 3);
				}
				t = new Target(line, file, col);

				if(!pastDefinitionStart && !inComment && !inAliasCode){
					if(c == '\n' || Character.isWhitespace(c)){
						continue;
					}
					pastLabel = c == '/' || c == '\'' || c == '"';
					pastDefinitionStart = true;
				}

				/* Strings and comments override basically everything */
				if(inLineComment){
					if(c == '\n'){
						inLineComment = false;
						inComment = false;
					}
					if(!inAliasCode){
						continue;
					}
				}
				if(inMultilineComment){
					if(c == '*' && c2 == '/'){
						boolean wasDocBlock = inDocBlockComment;
						inMultilineComment = inDocBlockComment = inComment = false;
						if(!inAliasCode){
							if(wasDocBlock){
								buffer(AliasTokenType.DOCBLOCK, t);
							}
							i++;
							continue;
						}
					}
					if(inDocBlockComment || inAliasCode){
						buf.append(c);
						continue;
					} else {
						continue;
					}
				}
				if(inQuote){
					if(c == '\\'){
						if(c2 == '\'' || c2 == '"'){
							buf.append(c2);
							i++;
							continue;
						}
					}
				}
				boolean skipProcessing = false;
				if(!inComment){
					if(c == '\'' && inSingleString){
						inQuote = false;
						inSingleString = false;
						if(!inAliasCode){
							if(!inOptionalVariable){
								validateLit(buf.toString());
							}
							buffer(AliasTokenType.LIT, t);
							continue;
						}
						skipProcessing = true;
					}
					if(c == '"' && inDoubleString){
						inQuote = false;
						inDoubleString = false;
						if(!inAliasCode){
							if(!inOptionalVariable){
								validateLit(buf.toString());
							}
							buffer(AliasTokenType.LIT, t);
							continue;
						}
						skipProcessing = true;
					}
					if(!skipProcessing){
						if(c == '\'' && !inQuote){
							// Start single string
							inQuote = true;
							inSingleString = true;
							singleQuoteStart = t;
							if(!inAliasCode){
								continue;
							}
						}
						if(c == '"' && !inQuote){
							inQuote = true;
							inDoubleString = true;
							doubleQuoteStart = t;
							if(!inAliasCode){
								continue;
							}
						}
					}
					if(inQuote && !inAliasCode){
						buf.append(c);
						continue;
					}
				}
				if(c == '#' || (c == '/' && c2 == '/') && !inQuote){
					inComment = true;
					inLineComment = true;
					if(!inAliasCode){
						endToken();
						if(c == '/'){
							i++;
						}
						continue;
					}
				}
				if(c == '/' && c2 == '*' && !inQuote){
					int skip = 1;
					inComment = true;
					inMultilineComment = true;
					multilineCommentStart = t;
					if(c3 == '*'){
						skip++;
						inDocBlockComment = true;
					}
					if(!inAliasCode){
						endToken();
						i += skip;
						continue;
					}
				}
				/* End string/comment handling */

				if(c == ':'){
					if(pastLabel){
						throw new ConfigCompileException("Unexpected symbol \":\", this may only be used as the command label.", t);
					}
					pastLabel = true;
					buffer(AliasTokenType.LABEL, t);
					continue;
				}

				if(!pastLabel){
					if(Character.isWhitespace(c)){
						continue;
					}
					buf.append(c);
					continue;
				}

				if(inAliasCode){
					// Once in the alias code, we can be in either two states, looking for the multiline start, or any
					// other code. Whitespace is not taken care of here, so we need to handle it. (i.e. ignore it)
					if(!pastMultiline && Character.isWhitespace(c) && c != '\n'){
						continue;
					}
					if(pastMultiline){
						if(!inMultiline){
							if(c == '\n'){
								// This is the end of the alias code. We need to append the code then reset all the variables.
								buffer(AliasTokenType.CODE, t);
								buffer(AliasTokenType.ALIAS_END, t);
								resetStates();
								continue;
							}
						} else if(!inQuote && !inComment){
							// We're done with the multiline possibly.
							if(c == '<' && c2 == '<' && c3 == '<'){
								if(isNewStyleMultiline){
									throw new ConfigCompileException("Unexpected multiline end symbol type, expected \"?>\" but found \"<<<\"", t);
								}
								i += 2;
								buffer(AliasTokenType.CODE, t);
								buffer(AliasTokenType.ALIAS_END, t);
								resetStates();
								continue;
							}
							if(c == '?' && c2 == '>'){
								if(!isNewStyleMultiline){
									throw new ConfigCompileException("Unexpected multiline end symbol type, expected \"<<<\" but found \"?>\"", t);
								}
								i++;
								buffer(AliasTokenType.CODE, t);
								buffer(AliasTokenType.ALIAS_END, t);
								resetStates();
								continue;
							}
						}
						buf.append(c);
						continue;
					}
					if(!pastMultiline){
						if(c == '>' && c2 == '>' && c3 == '>'){
							isNewStyleMultiline = false;
							inMultiline = true;
							i += 2;
							pastMultiline = true;
							continue;
						} else if(c == '<' && c2 == '?' && c3 == 'm' && c4 == 's'){
							isNewStyleMultiline = true;
							inMultiline = true;
							i += 3;
							pastMultiline = true;
							continue;
						}
						if((c == '<' && c2 == '<' && c3 == '<')
								|| (c == '?' && c2 == '>')){
							throw new ConfigCompileException("Unexpected multiline end symbol", t);
						}
						buf.append(c);
						pastMultiline = true;
						continue;
					}
				}

				if(Character.isWhitespace(c) && !inQuote && c != '\n'){
					// Ignore this, but end the previous token
					endToken();
					continue;
				}

				if(c == '$' && buf.length() == 0){
					inVariable = true;
				}

				if(c == '['){
					if(inOptionalVariable){
						throw new ConfigCompileException("Unexpected left bracket", t);
					}
					endToken();
					inOptionalVariable = true;
					optionalVariableStart = t;
					buf.append('[');
					buffer(AliasTokenType.OPTIONAL_START, t);
					continue;
				}
				if(c == ']'){
					if(!inOptionalVariable){
						throw new ConfigCompileException("Unexpected right bracket", t);
					}
					endToken();
					buf.append(']');
					inOptionalVariable = false;
					buffer(AliasTokenType.OPTIONAL_END, t);
					continue;
				}
				if(c == '='){
					endToken();
					buf.append('=');
					if(inOptionalVariable){
						buffer(AliasTokenType.ASSIGN, t);
					} else {
						buffer(AliasTokenType.DEFINITION_END, t);
						inAliasCode = true;
						pastMultiline = false;
					}
					continue;
				}

				if(!inQuote && c == '\n'){
					endToken();
					buffer(AliasTokenType.ALIAS_END, t);
					continue;
				}

				buf.append(c);
			}
			if(inSingleString){
				throw new ConfigCompileException("Unended string", singleQuoteStart);
			}
			if(inDoubleString){
				throw new ConfigCompileException("Unended string", doubleQuoteStart);
			}
			if(inMultilineComment){
				throw new ConfigCompileException("Unended block comment", multilineCommentStart);
			}
			if(inOptionalVariable){
				throw new ConfigCompileException("Unended optional variable", optionalVariableStart);
			}

			endToken();
		}

		private void resetStates(){
			inAliasCode = inDoubleString = inMultiline =
					inOptionalVariable = inSingleString = inVariable =
					isNewStyleMultiline = pastDefinitionStart = pastLabel =
					pastMultiline = inQuote = inComment = inLineComment =
					inMultilineComment = inDocBlockComment = false;
		}

		private void validateLit(String lit) throws ConfigCompileException{
			if(lit.contains(" ") || lit.contains("\t") || lit.contains("\n")){
				throw new ConfigCompileException("Alias literals cannot contain whitespace", t);
			}
		}

		private final Pattern LIT_PATTERN = Pattern.compile("([\\[\\]=:\\$])");

		private void endToken() throws ConfigCompileException {
			if(buf.length() == 0){
				return;
			}
			if(inVariable){
				String var = buf.toString();
				if(!var.matches("^\\$[a-zA-Z0-9_]*$")){
					throw new ConfigCompileException("Invalid variable name", t);
				}
				buffer(AliasTokenType.VARIABLE, t);
				inVariable = false;
				return;
			}
			//Otherwise it's a lit
			Matcher m = LIT_PATTERN.matcher(buf.toString());
			if(m.find()){
				throw new ConfigCompileException("Unexpected symbol \"" + m.group(1) + "\" in alias definition (you may quote strings in the definition)", t);
			}
			buffer(AliasTokenType.LIT, t);
		}

		private void buffer(AliasTokenType type, Target t){
			// Re-work the column so that it starts at the beginning of the token, not the end
			Target myTarget = new Target(t.line(), t.file(), t.col() - buf.toString().length());
			tokens.add(new AliasToken(buf.toString(), type, myTarget));
			buf = new StringBuilder();
		}
	}

	public static class Alias {

	}

	public static class AliasToken {
		private String token;
		private AliasTokenType type;
		private Target t;

		public AliasToken(String token, AliasTokenType type, Target t){
			this.token = token;
			this.type = type;
			this.t = t;
		}

		@Override
		public String toString() {
			return "(" + type.name() + ") " + token;
		}
	}

	public static enum AliasTokenType {
		UNKNOWN,
		VARIABLE,
		OPTIONAL_START,
		OPTIONAL_END,
		ASSIGN,
		LABEL,
		LIT,
		DEFINITION_END,
		ALIAS_END,
		CODE,
		DOCBLOCK
	}
}