text:
package com.nhl.link.rest.it.noadapter;

import static org.junit.Assert.assertEquals;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.nhl.link.rest.it.fixture.cayenne.E17;
import com.nhl.link.rest.it.fixture.cayenne.E18;
import com.nhl.link.rest.it.fixture.resource.E17Resource;
import org.apache.cayenne.DataRow;
import org.apache.cayenne.query.SQLSelect;
import org.apache.cayenne.query.SQLTemplate;
import org.junit.Test;

import com.nhl.link.rest.it.fixture.JerseyTestOnDerby;
import com.nhl.link.rest.it.fixture.cayenne.E12;
import com.nhl.link.rest.it.fixture.cayenne.E12E13;
import com.nhl.link.rest.it.fixture.cayenne.E2;
import com.nhl.link.rest.it.fixture.cayenne.E3;
import com.nhl.link.rest.it.fixture.resource.E12Resource;
import com.nhl.link.rest.it.fixture.resource.E2Resource;

public class POST_Related_IT extends JerseyTestOnDerby {

	@Override
	protected void doAddResources(FeatureContext context) {
		context.register(E2Resource.class);
		context.register(E12Resource.class);
		context.register(E17Resource.class);
	}

	@Test
	public void testRelate_ToMany_New() {

		context.performGenericQuery(new SQLTemplate(E2.class, "INSERT INTO utest.e2 (id, name) values (24, 'xxx')"));

		Response r1 = target("/e2/24/e3s").request().post(
				Entity.entity("{\"name\":\"zzz\"}", MediaType.APPLICATION_JSON));

		assertEquals(Status.OK.getStatusCode(), r1.getStatus());
		assertEquals("{\"data\":[{REPLACED_ID,\"name\":\"zzz\",\"phoneNumber\":null}],\"total\":1}",
				r1.readEntity(String.class).replaceFirst("\"id\":[\\d]+", "REPLACED_ID"));

		assertEquals(1, SQLSelect.scalarQuery(E3.class, "SELECT count(1) FROM utest.e3").selectOne(context));

		DataRow row = SQLSelect.dataRowQuery("SELECT e2_id, name FROM utest.e3").lowerColumnNames().selectOne(context);
		assertEquals("zzz", row.get("name"));
		assertEquals(24, row.get("e2_id"));
	}

	@Test
	public void testRelate_ToMany_New_CompoundId() {

		newContext().performGenericQuery(
				new SQLTemplate(E17.class, "INSERT INTO utest.e17 (id1, id2, name) values (1, 1, 'aaa')"));

		Response r1 = target("/e17/e18s").matrixParam("parentId1", 1).matrixParam("parentId2", 1).request()
				.post(Entity.entity("{\"name\":\"xxx\"}", MediaType.APPLICATION_JSON));

		assertEquals(Status.OK.getStatusCode(), r1.getStatus());
		assertEquals("{\"data\":[{REPLACED_ID,\"name\":\"xxx\"}],\"total\":1}",
				r1.readEntity(String.class).replaceFirst("\"id\":[\\d]+", "REPLACED_ID"));

		assertEquals(1, SQLSelect.scalarQuery(E18.class, "SELECT count(1) FROM utest.e18").selectOne(context));

		DataRow row = SQLSelect.dataRowQuery("SELECT e17_id1, e17_id2, name FROM utest.e18").lowerColumnNames().selectOne(context);
		assertEquals("xxx", row.get("name"));
		assertEquals(1, row.get("e17_id1"));
		assertEquals(1, row.get("e17_id2"));
	}

	@Test
	public void testRelate_ToMany_MixedCollection() {

		context.performGenericQuery(new SQLTemplate(E2.class, "INSERT INTO utest.e2 (id, name) values (15, 'xxx')"));
		context.performGenericQuery(new SQLTemplate(E2.class, "INSERT INTO utest.e2 (id, name) values (16, 'xxx')"));

		context.performGenericQuery(new SQLTemplate(E3.class,
				"INSERT INTO utest.e3 (id, name, e2_id) values (7, 'zzz', 16)"));
		context.performGenericQuery(new SQLTemplate(E3.class,
				"INSERT INTO utest.e3 (id, name, e2_id) values (8, 'yyy', 15)"));
		context.performGenericQuery(new SQLTemplate(E3.class,
				"INSERT INTO utest.e3 (id, name, e2_id) values (9, 'aaa', 15)"));

		Response r1 = target("/e2/15/e3s").request().post(
				Entity.entity("[ {\"id\":8,\"name\":\"123\"}, {\"name\":\"newname\"} ]", MediaType.APPLICATION_JSON));

		assertEquals(Status.OK.getStatusCode(), r1.getStatus());
		assertEquals("{\"data\":[{\"id\":8,\"name\":\"123\",\"phoneNumber\":null},"
				+ "{\"id\":1,\"name\":\"newname\",\"phoneNumber\":null}],\"total\":2}", r1.readEntity(String.class));
		assertEquals(4, SQLSelect.scalarQuery(String.class, "SELECT count(1) FROM utest.e3").selectOne(context));
		assertEquals(3, SQLSelect.scalarQuery(String.class, "SELECT count(1) FROM utest.e3 WHERE e2_id = 15")
				.selectOne(context));

		// testing non-idempotency

		Response r2 = target("/e2/15/e3s").request().post(
				Entity.entity("[ {\"id\":8,\"name\":\"123\"}, {\"name\":\"newname\"} ]", MediaType.APPLICATION_JSON));

		assertEquals(Status.OK.getStatusCode(), r2.getStatus());
		assertEquals("{\"data\":[{\"id\":8,\"name\":\"123\",\"phoneNumber\":null},"
				+ "{\"id\":2,\"name\":\"newname\",\"phoneNumber\":null}],\"total\":2}", r2.readEntity(String.class));
		assertEquals(5, SQLSelect.scalarQuery(String.class, "SELECT count(1) FROM utest.e3").selectOne(context));
		assertEquals(4, SQLSelect.scalarQuery(String.class, "SELECT count(1) FROM utest.e3 WHERE e2_id = 15")
				.selectOne(context));
	}

	@Test
	public void testPOST_ToManyJoin() {

		context.performGenericQuery(new SQLTemplate(E12.class, "INSERT INTO utest.e12 (id) values (11)"));
		context.performGenericQuery(new SQLTemplate(E12.class, "INSERT INTO utest.e12 (id) values (12)"));
		context.performGenericQuery(new SQLTemplate(E12.class, "INSERT INTO utest.e13 (id) values (14)"));
		context.performGenericQuery(new SQLTemplate(E12.class, "INSERT INTO utest.e13 (id) values (15)"));
		context.performGenericQuery(new SQLTemplate(E12.class, "INSERT INTO utest.e13 (id) values (16)"));

		Response r1 = target("/e12/12/e1213").queryParam("exclude", "id").request()
				.post(Entity.entity("[{\"e13\":15},{\"e13\":14}]", MediaType.APPLICATION_JSON));

		assertEquals(Status.CREATED.getStatusCode(), r1.getStatus());
		assertEquals("{\"data\":[{},{}],\"total\":2}",
				r1.readEntity(String.class));

		assertEquals(2, SQLSelect.scalarQuery(E12E13.class, "SELECT count(1) FROM utest.e12_e13").selectOne(context));
		assertEquals(1, SQLSelect.scalarQuery(E12E13.class,
				"SELECT count(1) FROM utest.e12_e13 " + "WHERE e12_id = 12 AND e13_id = 14").selectOne(context));
		assertEquals(1, SQLSelect.scalarQuery(E12E13.class,
				"SELECT count(1) FROM utest.e12_e13 " + "WHERE e12_id = 12 AND e13_id = 15").selectOne(context));
	}

}


text:
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []

        stack = []
        node = root
        while node or stack:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            res.append(node.val)
            node = node.right

        return res

redpajama_set_name: RedPajamaGithub


text:
package com.google.bqq;

import com.google.cloud.bigquery.QueryParameterValue;
import com.google.cloud.bigquery.QueryRequest;
import com.google.cloud.bigquery.QueryResult;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

/**
 * Tests BQQClient class.
 */
public class BQQClientTest {
  private static final String EXAMPLE_QUERY_SQL = "SELECT "
      + "COUNT(UNIQUE(word)) "
      + "FROM [bigquery-public-data:samples.shakespeare]";

  @Rule public ExpectedException thrown = ExpectedException.none();

  @Test
  public void testConstructor_EmptyStringArguments() {
    thrown.expect(IllegalArgumentException.class);
    new BQQClient("", "");
  }

  @Test
  public void testConstructor_NullArguments() {
    thrown.expect(IllegalArgumentException.class);
    new BQQClient(null, null);
  }

  @Test
  public void testStartup_BadServiceAccountPath()
      throws FileNotFoundException, IOException {
    BQQClient c = new BQQClient("some_bs_project", "some_bs_key.json");
    thrown.expect(FileNotFoundException.class);
    thrown.expectMessage("some_bs_key.json (No such file or directory)");
    c.startup(10);
  }

  @Test
  public void testGetNumJobs_GivesAccurateCount() throws Exception {
    BQQClient c = new BQQClient();
    c.startup(1);

    for (int i = 0; i < 100; ++i) {
      c.queueQuery(EXAMPLE_QUERY_SQL, true);
    }

    Thread.sleep(5);
    System.out.println("Query count: " + c.getNumJobs());
    Assert.assertEquals(Integer.valueOf(99), c.getNumJobs());
    c.shutdown();
  }

  @Test
  public void testQueueQuery_QueuesQuery()
      throws FileNotFoundException, IOException,
      InterruptedException, BQQException, ExecutionException {
    BQQClient c = new BQQClient();
    c.startup(1);

    Future<QueryResult> f1 = c.queueQuery(QueryRequest.newBuilder(EXAMPLE_QUERY_SQL)
        .setUseLegacySql(true).build());
    Future<QueryResult> f2 = c.queueQuery(EXAMPLE_QUERY_SQL, true);

    QueryResult r1 = BQQClient.getQueryResult(f1);
    QueryResult r2 = BQQClient.getQueryResult(f2);

    Assert.assertEquals(r1.getTotalRows(), r2.getTotalRows());
  }

  @Test
  public void testGetQueryResult_PassesBQErrors_LegacySql()
      throws FileNotFoundException, IOException,
      InterruptedException, ExecutionException, BQQException {
    BQQClient c = new BQQClient();
    c.startup(1);

    // this should be a failing query. mExampleQuery is legacy sql,
    Future<QueryResult> f = c.queueQuery(QueryRequest.newBuilder(EXAMPLE_QUERY_SQL)
        .setUseLegacySql(false).build());

    thrown.expect(BQQException.class);
    BQQClient.getQueryResult(f);
  }

  @Test
  public void testGetQueryResult_PassesBQErrors_NoSQLQuery()
      throws FileNotFoundException, IOException,
      InterruptedException, BQQException, ExecutionException {
    BQQClient c = new BQQClient();
    c.startup(1);

    // this should be a failing query.
    Future<QueryResult> f = c.queueQuery("", false);

    thrown.expect(BQQException.class);
    BQQClient.getQueryResult(f);
  }

  @Test
  public void testGetQueryResult_PassesBQErrors_MissingParameters()
      throws FileNotFoundException, IOException,
      InterruptedException, BQQException, ExecutionException {
    BQQClient c = new BQQClient();
    c.startup(1);

    // this should be a failing query, parameters not all set, missing corpus.
    int minWordCount = 10;
    String parameterizedSql = "SELECT word, word_count\n"
        + "FROM `bigquery-public-data.samples.shakespeare`\n"
        + "WHERE corpus = @corpus\n"
        + "AND word_count >= @min_word_count\n"
        + "ORDER BY word_count DESC";

    QueryRequest parameterizedQueryRequest = QueryRequest
        .newBuilder(parameterizedSql)
        .addNamedParameter("min_word_count", QueryParameterValue.int64(minWordCount))
        .setUseLegacySql(false)
        .build();
    Future<QueryResult> f = c.queueQuery(parameterizedQueryRequest);

    thrown.expect(BQQException.class);
    BQQClient.getQueryResult(f);
  }

  @Test
  public void testGetQueryResult_PassesBQErrors_ProjectNotFound()
      throws FileNotFoundException, IOException,
      InterruptedException, BQQException, ExecutionException {
    BQQClient c = new BQQClient();
    c.startup(1);

    // this should be a failing query, parameters not all set, missing corpus.
    Future<QueryResult> f = c.queueQuery(
        "SELECT count(*) FROM [some-bs-project:some.bstable]", true);

    thrown.expect(BQQException.class);
    BQQClient.getQueryResult(f);
  }

  @Test
  public void testShutdown_CanTeardownThreadPool() throws Exception {
    BQQClient c = new BQQClient();
    c.startup(3);

    // Schedule some tasks
    for (int i = 0; i < 10; ++i) {
      c.queueQuery(EXAMPLE_QUERY_SQL, true);
    }
    Thread.sleep(10);
    c.shutdown();
  }
}


text:
package superheroes.dao.impl;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.*;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import superheroes.dao.CharacterDao;
import superheroes.entity.Character;

import java.util.List;

/**
 * Created by catop on 4/3/15.
 */
@Component
public class CharacterDaoHibernateImpl implements CharacterDao {

    private static final Logger LOGGER = LogManager.getLogger(CharacterDaoHibernateImpl.class.getName());

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * Attempts to represent the character entity in the database.
     * Note that you should only use this method if you are certain that this entity
     * don't already exist in the database, in which case this is the fastest way
     * to save the entity.  If you are unsure, then use the updateCharacter method
     * instead.
     *
     * @param character The character entity object to be saved
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveCharacter(Character character) {
        LOGGER.trace("IN: character=" + character);
        Session session = sessionFactory.getCurrentSession();
        session.save(character);
    }

    /**
     * Attempts to represent the character entity in the database.
     * It is safe to use this method to save an entity that has not
     * already been saved in the database, but note that this convenience
     * comes at a slight performance cost.
     *
     * @param character The character entity object to be saved
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCharacter(Character character) {
        LOGGER.trace("IN: character=" + character);
        Session session = sessionFactory.getCurrentSession();
        session.saveOrUpdate(character);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void mergeCharacter(Character character) {
        LOGGER.trace("IN: character=" + character);
        Session session = sessionFactory.getCurrentSession();
        session.merge(character);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void mergeCharacters(List<Character> characters) {
        LOGGER.trace("IN: characters.size=" + (characters == null ? null : characters.size()));
        Session session = sessionFactory.getCurrentSession();
        for (Character character : characters) {
            session.merge(character);
        }
    }

    /**
     * Deletes the character entity from its representation in
     * the database.  Note that this does not nullify the
     * comic Java reference, which will continue to live
     * while in scope.
     *
     * @param character The character entity to be deleted from the database
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteCharacter(Character character) {
        LOGGER.trace("IN: character=" + character);
        Session session = sessionFactory.getCurrentSession();
        session.delete(character);
    }

    /**
     * Returns a specific character entity object found by id.
     * If no object is found, then a null value is returned.
     *
     * @param id The character id the desired character entity possess
     * @return Returns a Character entity object or null
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Character getCharacterById(Integer id) {
        LOGGER.trace("IN: id=" + id);
        Session session = sessionFactory.getCurrentSession();
        Character character = (Character) session.get(Character.class, id);
        initializeCharacter(character);
        return character;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Character getCharacterByName(String name) {
        LOGGER.trace("IN: name=" + name);
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(superheroes.entity.Character.class);
        Character character = (Character) criteria.setMaxResults(1).add(Restrictions.like("name", name)).uniqueResult();
        return character;
    }

    /**
     * Uses HQL to return all character entities managed by Hibernate
     *
     * @return Returns a list of character entities
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public List<Character> getAllCharacters() {
        LOGGER.trace("IN");
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery("from superheroes.entity.Character");
        List<Character> characters = query.list();
        LOGGER.trace("OUT: characters.size=" + characters.size());
        return characters;
    }

    /**
     * Returns a list of characters ordered by popularity.  Note that this
     * particular implementation will not return results if a character
     * lacks data for the description or thumbnail_path fields.
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public List<Character> getCharactersByPopularity(Integer limit) {
        LOGGER.trace("IN: limit=" + limit);
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(superheroes.entity.Character.class);
        criteria.add(Restrictions.neOrIsNotNull("description",""));
        criteria.add(Restrictions.neOrIsNotNull("thumbnailPath",""));
        List<Character> characters = criteria.setMaxResults(limit).addOrder(Order.desc("popularity")).setReadOnly(true).list();
        return characters;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public List<Character> getCharacters(Integer limit, Integer offset) {
        LOGGER.trace("IN: limit=" + limit + ", offset=" + offset);
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(superheroes.entity.Character.class);
        List<Character> characters = criteria.setFirstResult(offset).setReadOnly(true).setMaxResults(limit).list();
        return characters;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public List<Character> getCharactersByName(String name) {
        LOGGER.trace("IN: name=" + name);
        name = "%" + name + "%";
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(superheroes.entity.Character.class);
        List<Character> characters = criteria.setMaxResults(10).add(Restrictions.like("name", name)).list();
        for (Character character : characters) {
            initializeCharacter(character);
        }
        return characters;
    }

    private Character initializeCharacter(Character character) {
        LOGGER.trace("IN");
        if (character != null) {
            Hibernate.initialize(character.getComics());
            Hibernate.initialize(character.getEvents());
            Hibernate.initialize(character.getSeries());
            Hibernate.initialize(character.getStories());
            Hibernate.initialize(character.getUrls());
        }
        return character;
    }
}


text:
package baryberri.a6_2_readingrawfolder;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    Button button;
    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.button);
        editText = (EditText)findViewById(R.id.editText);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    InputStream is = getResources().openRawResource(R.raw.rawfile);

                    // is.available() returns the byte size that can be read in the given input stream.
                    byte[] readText = new byte[is.available()];
                    is.read(readText);
                    is.close();

                    editText.setText(new String(readText));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}


text:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const { create: createResolver } = require("enhanced-resolve");
const asyncLib = require("neo-async");
const AsyncQueue = require("./util/AsyncQueue");
const createHash = require("./util/createHash");
const { join, dirname, relative } = require("./util/fs");

/** @typedef {import("./WebpackError")} WebpackError */
/** @typedef {import("./logging/Logger").Logger} Logger */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */

const resolveContext = createResolver({
	resolveToContext: true
});
const resolve = createResolver({
	extensions: [".js", ".json", ".node"]
});

let FS_ACCURACY = 2000;

const EMPTY_SET = new Set();

const RBDT_RESOLVE = 0;
const RBDT_RESOLVE_DIRECTORY = 1;
const RBDT_RESOLVE_FILE = 2;
const RBDT_DIRECTORY = 3;
const RBDT_FILE = 4;
const RBDT_DIRECTORY_DEPENDENCIES = 5;
const RBDT_FILE_DEPENDENCIES = 6;

const INVALID = Symbol("invalid");

/**
 * @typedef {Object} FileSystemInfoEntry
 * @property {number} safeTime
 * @property {number=} timestamp
 * @property {string=} timestampHash
 */

/**
 * @typedef {Object} Snapshot
 * @property {number=} startTime
 * @property {Map<string, FileSystemInfoEntry>=} fileTimestamps
 * @property {Map<string, string>=} fileHashes
 * @property {Map<string, FileSystemInfoEntry>=} contextTimestamps
 * @property {Map<string, string>=} contextHashes
 * @property {Map<string, boolean>=} missingExistance
 * @property {Map<string, string>=} managedItemInfo
 */

/**
 * @typedef {Object} ResolveBuildDependenciesResult
 * @property {Set<string>} files list of files
 * @property {Set<string>} directories list of directories
 * @property {Set<string>} missing list of missing entries
 * @property {Map<string, string>} resolveResults stored resolve results
 * @property {Object} resolveDependencies dependencies of the resolving
 * @property {Set<string>} resolveDependencies.files list of files
 * @property {Set<string>} resolveDependencies.directories list of directories
 * @property {Set<string>} resolveDependencies.missing list of missing entries
 */

/**
 * istanbul ignore next
 * @param {number} mtime mtime
 */
const applyMtime = mtime => {
	if (FS_ACCURACY > 1 && mtime % 2 !== 0) FS_ACCURACY = 1;
	else if (FS_ACCURACY > 10 && mtime % 20 !== 0) FS_ACCURACY = 10;
	else if (FS_ACCURACY > 100 && mtime % 200 !== 0) FS_ACCURACY = 100;
	else if (FS_ACCURACY > 1000 && mtime % 2000 !== 0) FS_ACCURACY = 1000;
};

/**
 * @template T
 * @template K
 * @param {Map<T, K>} a source map
 * @param {Map<T, K>} b joining map
 * @returns {Map<T, K>} joined map
 */
const mergeMaps = (a, b) => {
	if (!b || b.size === 0) return a;
	if (!a || a.size === 0) return b;
	const map = new Map(a);
	for (const [key, value] of b) {
		map.set(key, value);
	}
	return map;
};

/**
 * Finding file or directory to manage
 * @param {string} managedPath path that is managing by {@link FileSystemInfo}
 * @param {string} path path to file or directory
 * @returns {string|null} managed item
 * @example
 * getManagedItem(
 *   '/Users/user/my-project/node_modules/',
 *   '/Users/user/my-project/node_modules/package/index.js'
 * ) === '/Users/user/my-project/node_modules/package'
 * getManagedItem(
 *   '/Users/user/my-project/node_modules/',
 *   '/Users/user/my-project/node_modules/package1/node_modules/package2'
 * ) === '/Users/user/my-project/node_modules/package1/node_modules/package2'
 * getManagedItem(
 *   '/Users/user/my-project/node_modules/',
 *   '/Users/user/my-project/node_modules/.bin/script.js'
 * ) === null // hidden files are disallowed as managed items
 * getManagedItem(
 *   '/Users/user/my-project/node_modules/',
 *   '/Users/user/my-project/node_modules/package'
 * ) === '/Users/user/my-project/node_modules/package'
 */
const getManagedItem = (managedPath, path) => {
	let i = managedPath.length;
	let slashes = 1;
	let startingPosition = true;
	loop: while (i < path.length) {
		switch (path.charCodeAt(i)) {
			case 47: // slash
			case 92: // backslash
				if (--slashes === 0) break loop;
				startingPosition = true;
				break;
			case 46: // .
				// hidden files are disallowed as managed items
				// it's probably .yarn-integrity or .cache
				if (startingPosition) return null;
				break;
			case 64: // @
				if (!startingPosition) return null;
				slashes++;
				break;
			default:
				startingPosition = false;
				break;
		}
		i++;
	}
	if (i === path.length) slashes--;
	// return null when path is incomplete
	if (slashes !== 0) return null;
	// if (path.slice(i + 1, i + 13) === "node_modules")
	if (
		path.length >= i + 13 &&
		path.charCodeAt(i + 1) === 110 &&
		path.charCodeAt(i + 2) === 111 &&
		path.charCodeAt(i + 3) === 100 &&
		path.charCodeAt(i + 4) === 101 &&
		path.charCodeAt(i + 5) === 95 &&
		path.charCodeAt(i + 6) === 109 &&
		path.charCodeAt(i + 7) === 111 &&
		path.charCodeAt(i + 8) === 100 &&
		path.charCodeAt(i + 9) === 117 &&
		path.charCodeAt(i + 10) === 108 &&
		path.charCodeAt(i + 11) === 101 &&
		path.charCodeAt(i + 12) === 115
	) {
		// if this is the end of the path
		if (path.length === i + 13) {
			// return the node_modules directory
			// it's special
			return path;
		}
		const c = path.charCodeAt(i + 13);
		// if next symbol is slash or backslash
		if (c === 47 || c === 92) {
			// Managed subpath
			return getManagedItem(path.slice(0, i + 14), path);
		}
	}
	return path.slice(0, i);
};

/**
 * @param {FileSystemInfoEntry} entry file system info entry
 * @returns {boolean} existance flag
 */
const toExistance = entry => {
	return Boolean(entry);
};

/**
 * Used to access information about the filesystem in a cached way
 */
class FileSystemInfo {
	/**
	 * @param {InputFileSystem} fs file system
	 * @param {Object} options options
	 * @param {Iterable<string>=} options.managedPaths paths that are only managed by a package manager
	 * @param {Iterable<string>=} options.immutablePaths paths that are immutable
	 * @param {Logger=} options.logger logger used to log invalid snapshots
	 */
	constructor(fs, { managedPaths = [], immutablePaths = [], logger } = {}) {
		this.fs = fs;
		this.logger = logger;
		this._remainingLogs = logger ? 40 : 0;
		this._loggedPaths = logger ? new Set() : undefined;
		/** @type {WeakMap<Snapshot, boolean | (function(WebpackError=, boolean=): void)[]>} */
		this._snapshotCache = new WeakMap();
		/** @type {Map<string, FileSystemInfoEntry | "ignore" | null>} */
		this._fileTimestamps = new Map();
		/** @type {Map<string, string>} */
		this._fileHashes = new Map();
		/** @type {Map<string, FileSystemInfoEntry | "ignore" | null>} */
		this._contextTimestamps = new Map();
		/** @type {Map<string, string>} */
		this._contextHashes = new Map();
		/** @type {Map<string, string>} */
		this._managedItems = new Map();
		/** @type {AsyncQueue<string, string, FileSystemInfoEntry | null>} */
		this.fileTimestampQueue = new AsyncQueue({
			name: "file timestamp",
			parallelism: 30,
			processor: this._readFileTimestamp.bind(this)
		});
		/** @type {AsyncQueue<string, string, string | null>} */
		this.fileHashQueue = new AsyncQueue({
			name: "file hash",
			parallelism: 10,
			processor: this._readFileHash.bind(this)
		});
		/** @type {AsyncQueue<string, string, FileSystemInfoEntry | null>} */
		this.contextTimestampQueue = new AsyncQueue({
			name: "context timestamp",
			parallelism: 2,
			processor: this._readContextTimestamp.bind(this)
		});
		/** @type {AsyncQueue<string, string, string | null>} */
		this.contextHashQueue = new AsyncQueue({
			name: "context hash",
			parallelism: 2,
			processor: this._readContextHash.bind(this)
		});
		/** @type {AsyncQueue<string, string, string | null>} */
		this.managedItemQueue = new AsyncQueue({
			name: "managed item info",
			parallelism: 10,
			processor: this._getManagedItemInfo.bind(this)
		});
		/** @type {AsyncQueue<string, string, Set<string>>} */
		this.managedItemDirectoryQueue = new AsyncQueue({
			name: "managed item directory info",
			parallelism: 10,
			processor: this._getManagedItemDirectoryInfo.bind(this)
		});
		this.managedPaths = Array.from(managedPaths);
		this.managedPathsWithSlash = this.managedPaths.map(p =>
			join(fs, p, "_").slice(0, -1)
		);
		this.immutablePaths = Array.from(immutablePaths);
		this.immutablePathsWithSlash = this.immutablePaths.map(p =>
			join(fs, p, "_").slice(0, -1)
		);
	}

	_log(path, reason, ...args) {
		const key = path + reason;
		if (this._loggedPaths.has(key)) return;
		this._loggedPaths.add(key);
		this.logger.debug(`${path} invalidated because ${reason}`, ...args);
		if (--this._remainingLogs === 0) {
			this.logger.debug(
				"Logging limit has been reached and no futher logging will be emitted by FileSystemInfo"
			);
		}
	}

	/**
	 * @param {Map<string, FileSystemInfoEntry | "ignore" | null>} map timestamps
	 * @returns {void}
	 */
	addFileTimestamps(map) {
		for (const [path, ts] of map) {
			this._fileTimestamps.set(path, ts);
		}
	}

	/**
	 * @param {Map<string, FileSystemInfoEntry | "ignore" | null>} map timestamps
	 * @returns {void}
	 */
	addContextTimestamps(map) {
		for (const [path, ts] of map) {
			this._contextTimestamps.set(path, ts);
		}
	}

	/**
	 * @param {string} path file path
	 * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
	 * @returns {void}
	 */
	getFileTimestamp(path, callback) {
		const cache = this._fileTimestamps.get(path);
		if (cache !== undefined) return callback(null, cache);
		this.fileTimestampQueue.add(path, callback);
	}

	/**
	 * @param {string} path context path
	 * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
	 * @returns {void}
	 */
	getContextTimestamp(path, callback) {
		const cache = this._contextTimestamps.get(path);
		if (cache !== undefined) return callback(null, cache);
		this.contextTimestampQueue.add(path, callback);
	}

	/**
	 * @param {string} path file path
	 * @param {function(WebpackError=, string=): void} callback callback function
	 * @returns {void}
	 */
	getFileHash(path, callback) {
		const cache = this._fileHashes.get(path);
		if (cache !== undefined) return callback(null, cache);
		this.fileHashQueue.add(path, callback);
	}

	/**
	 * @param {string} path context path
	 * @param {function(WebpackError=, string=): void} callback callback function
	 * @returns {void}
	 */
	getContextHash(path, callback) {
		const cache = this._contextHashes.get(path);
		if (cache !== undefined) return callback(null, cache);
		this.contextHashQueue.add(path, callback);
	}

	/**
	 * @param {string} context context directory
	 * @param {Iterable<string>} deps dependencies
	 * @param {function(Error=, ResolveBuildDependenciesResult=): void} callback callback function
	 * @returns {void}
	 */
	resolveBuildDependencies(context, deps, callback) {
		/** @type {Set<string>} */
		const files = new Set();
		/** @type {Set<string>} */
		const directories = new Set();
		/** @type {Set<string>} */
		const missing = new Set();
		/** @type {Set<string>} */
		const resolveFiles = new Set();
		/** @type {Set<string>} */
		const resolveDirectories = new Set();
		/** @type {Set<string>} */
		const resolveMissing = new Set();
		/** @type {Map<string, string>} */
		const resolveResults = new Map();
		/** @type {asyncLib.QueueObject<{type: number, path: string, context?: string, expected?: string }, Error>} */
		const queue = asyncLib.queue(
			({ type, context, path, expected }, callback) => {
				const resolveDirectory = path => {
					const key = `d\n${context}\n${path}`;
					if (resolveResults.has(key)) {
						return callback();
					}
					resolveContext(
						context,
						path,
						{
							fileDependencies: resolveFiles,
							contextDependencies: resolveDirectories,
							missingDependencies: resolveMissing
						},
						(err, result) => {
							if (err) {
								if (
									err.code === "ENOENT" ||
									err.code === "UNDECLARED_DEPENDENCY"
								)
									return callback();
								return callback(err);
							}
							resolveResults.set(key, result);
							queue.push({
								type: RBDT_DIRECTORY,
								path: result
							});
							callback();
						}
					);
				};
				const resolveFile = path => {
					const key = `f\n${context}\n${path}`;
					if (resolveResults.has(key)) {
						return callback();
					}
					resolve(
						context,
						path,
						{
							fileDependencies: resolveFiles,
							contextDependencies: resolveDirectories,
							missingDependencies: resolveMissing
						},
						(err, result) => {
							if (expected) {
								if (result === expected) {
									resolveResults.set(key, result);
								}
							} else {
								if (err) {
									if (
										err.code === "ENOENT" ||
										err.code === "UNDECLARED_DEPENDENCY"
									)
										return callback();
									return callback(err);
								}
								resolveResults.set(key, result);
								queue.push({
									type: RBDT_FILE,
									path: result
								});
							}
							callback();
						}
					);
				};
				switch (type) {
					case RBDT_RESOLVE: {
						const isDirectory = /[\\/]$/.test(path);
						if (isDirectory) {
							resolveDirectory(path.slice(0, path.length - 1));
						} else {
							resolveFile(path);
						}
						break;
					}
					case RBDT_RESOLVE_DIRECTORY: {
						resolveDirectory(path);
						break;
					}
					case RBDT_RESOLVE_FILE: {
						resolveFile(path);
						break;
					}
					case RBDT_FILE: {
						if (files.has(path)) {
							callback();
							break;
						}
						this.fs.realpath(path, (err, realPath) => {
							if (err) return callback(err);
							if (realPath !== path) {
								resolveFiles.add(path);
							}
							if (!files.has(realPath)) {
								files.add(realPath);
								queue.push({
									type: RBDT_FILE_DEPENDENCIES,
									path: realPath
								});
							}
							callback();
						});
						break;
					}
					case RBDT_DIRECTORY: {
						if (directories.has(path)) {
							callback();
							break;
						}
						this.fs.realpath(path, (err, realPath) => {
							if (err) return callback(err);
							if (realPath !== path) {
								resolveFiles.add(path);
							}
							if (!directories.has(realPath)) {
								directories.add(realPath);
								queue.push({
									type: RBDT_DIRECTORY_DEPENDENCIES,
									path: realPath
								});
							}
							callback();
						});
						break;
					}
					case RBDT_FILE_DEPENDENCIES: {
						/** @type {NodeModule} */
						const module = require.cache[path];
						if (module && Array.isArray(module.children)) {
							children: for (const child of module.children) {
								let childPath = child.filename;
								if (childPath) {
									queue.push({
										type: RBDT_FILE,
										path: childPath
									});
									if (childPath.endsWith(".js"))
										childPath = childPath.slice(0, -3);
									const context = dirname(this.fs, path);
									for (const modulePath of module.paths) {
										if (childPath.startsWith(modulePath)) {
											const request = childPath.slice(modulePath.length + 1);
											queue.push({
												type: RBDT_RESOLVE_FILE,
												context,
												path: request,
												expected: childPath
											});
											continue children;
										}
									}
									let request = relative(this.fs, context, childPath);
									request = request.replace(/\\/g, "/");
									if (!request.startsWith("../")) request = `./${request}`;
									queue.push({
										type: RBDT_RESOLVE_FILE,
										context,
										path: request,
										expected: child.filename
									});
								}
							}
						} else {
							// Unable to get dependencies from module system
							// This may be because of an incomplete require.cache implementation like in jest
							// Assume requires stay in directory and add the whole directory
							const directory = dirname(this.fs, path);
							queue.push({
								type: RBDT_DIRECTORY,
								path: directory
							});
						}
						callback();
						break;
					}
					case RBDT_DIRECTORY_DEPENDENCIES: {
						const match = /(^.+[\\/]node_modules[\\/](?:@[^\\/]+[\\/])?[^\\/]+)/.exec(
							path
						);
						const packagePath = match ? match[1] : path;
						const packageJson = join(this.fs, packagePath, "package.json");
						this.fs.readFile(packageJson, (err, content) => {
							if (err) {
								if (err.code === "ENOENT") {
									resolveMissing.add(packageJson);
									const parent = dirname(this.fs, packagePath);
									if (parent !== packagePath) {
										queue.push({
											type: RBDT_DIRECTORY_DEPENDENCIES,
											path: parent
										});
									}
									callback();
									return;
								}
								return callback(err);
							}
							resolveFiles.add(packageJson);
							let packageData;
							try {
								packageData = JSON.parse(content.toString("utf-8"));
							} catch (e) {
								return callback(e);
							}
							const depsObject = packageData.dependencies;
							if (typeof depsObject === "object" && depsObject) {
								for (const dep of Object.keys(depsObject)) {
									queue.push({
										type: RBDT_RESOLVE_DIRECTORY,
										context: packagePath,
										path: dep
									});
								}
							}
							callback();
						});
						break;
					}
				}
			},
			50
		);
		queue.drain = () => {
			callback(null, {
				files,
				directories,
				missing,
				resolveResults,
				resolveDependencies: {
					files: resolveFiles,
					directories: resolveDirectories,
					missing: resolveMissing
				}
			});
		};
		queue.error = err => {
			callback(err);
			callback = () => {};
		};
		let jobQueued = false;
		for (const dep of deps) {
			queue.push({
				type: RBDT_RESOLVE,
				context,
				path: dep
			});
			jobQueued = true;
		}
		if (!jobQueued) {
			// queue won't call drain when no jobs are queue
			queue.drain();
		}
	}

	/**
	 * @param {Map<string, string>} resolveResults results from resolving
	 * @param {function(Error=, boolean=): void} callback callback with true when resolveResults resolve the same way
	 * @returns {void}
	 */
	checkResolveResultsValid(resolveResults, callback) {
		asyncLib.eachLimit(
			resolveResults,
			20,
			([key, expectedResult], callback) => {
				const [type, context, path] = key.split("\n");
				switch (type) {
					case "d":
						resolveContext(context, path, {}, (err, result) => {
							if (err) return callback(err);
							if (result !== expectedResult) return callback(INVALID);
							callback();
						});
						break;
					case "f":
						resolve(context, path, {}, (err, result) => {
							if (err) return callback(err);
							if (result !== expectedResult) return callback(INVALID);
							callback();
						});
						break;
					default:
						callback(new Error("Unexpected type in resolve result key"));
						break;
				}
			},
			/**
			 * @param {Error | typeof INVALID=} err error or invalid flag
			 * @returns {void}
			 */
			err => {
				if (err === INVALID) {
					return callback(null, false);
				}
				if (err) {
					return callback(err);
				}
				return callback(null, true);
			}
		);
	}

	/**
	 *
	 * @param {number} startTime when processing the files has started
	 * @param {Iterable<string>} files all files
	 * @param {Iterable<string>} directories all directories
	 * @param {Iterable<string>} missing all missing files or directories
	 * @param {Object} options options object (for future extensions)
	 * @param {boolean=} options.hash should use hash to snapshot
	 * @param {function(WebpackError=, Snapshot=): void} callback callback function
	 * @returns {void}
	 */
	createSnapshot(startTime, files, directories, missing, options, callback) {
		/** @type {Map<string, FileSystemInfoEntry>} */
		const fileTimestamps = new Map();
		/** @type {Map<string, string>} */
		const fileHashes = new Map();
		/** @type {Map<string, FileSystemInfoEntry>} */
		const contextTimestamps = new Map();
		/** @type {Map<string, string>} */
		const contextHashes = new Map();
		/** @type {Map<string, boolean>} */
		const missingExistance = new Map();
		/** @type {Map<string, string>} */
		const managedItemInfo = new Map();

		/** @type {Set<string>} */
		const managedItems = new Set();

		let jobs = 1;
		const jobDone = () => {
			if (--jobs === 0) {
				const snapshot = {};
				if (startTime) snapshot.startTime = startTime;
				if (fileTimestamps.size !== 0) snapshot.fileTimestamps = fileTimestamps;
				if (fileHashes.size !== 0) snapshot.fileHashes = fileHashes;
				if (contextTimestamps.size !== 0)
					snapshot.contextTimestamps = contextTimestamps;
				if (contextHashes.size !== 0) snapshot.contextHashes = contextHashes;
				if (missingExistance.size !== 0)
					snapshot.missingExistance = missingExistance;
				if (managedItemInfo.size !== 0)
					snapshot.managedItemInfo = managedItemInfo;
				this._snapshotCache.set(snapshot, true);
				callback(null, snapshot);
			}
		};
		const jobError = () => {
			if (jobs > 0) {
				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
				jobs = -100000000;
				callback(null, null);
			}
		};
		if (files) {
			if (options && options.hash) {
				files: for (const path of files) {
					for (const immutablePath of this.immutablePathsWithSlash) {
						if (path.startsWith(immutablePath)) {
							continue files;
						}
					}
					for (const managedPath of this.managedPathsWithSlash) {
						if (path.startsWith(managedPath)) {
							const managedItem = getManagedItem(managedPath, path);
							if (managedItem) {
								managedItems.add(managedItem);
								continue files;
							}
						}
					}
					const cache = this._fileHashes.get(path);
					if (cache !== undefined) {
						fileHashes.set(path, cache);
					} else {
						jobs++;
						this.fileHashQueue.add(path, (err, entry) => {
							if (err) {
								if (this.logger) {
									this.logger.debug(
										`Error snapshotting file hash of ${path}: ${err}`
									);
								}
								jobError();
							} else {
								fileHashes.set(path, entry);
								jobDone();
							}
						});
					}
				}
			} else {
				files: for (const path of files) {
					for (const immutablePath of this.immutablePathsWithSlash) {
						if (path.startsWith(immutablePath)) {
							continue files;
						}
					}
					for (const managedPath of this.managedPathsWithSlash) {
						if (path.startsWith(managedPath)) {
							const managedItem = getManagedItem(managedPath, path);
							if (managedItem) {
								managedItems.add(managedItem);
								continue files;
							}
						}
					}
					const cache = this._fileTimestamps.get(path);
					if (cache !== undefined) {
						if (cache !== "ignore") {
							fileTimestamps.set(path, cache);
						}
					} else {
						jobs++;
						this.fileTimestampQueue.add(path, (err, entry) => {
							if (err) {
								if (this.logger) {
									this.logger.debug(
										`Error snapshotting file timestamp of ${path}: ${err}`
									);
								}
								jobError();
							} else {
								fileTimestamps.set(path, entry);
								jobDone();
							}
						});
					}
				}
			}
		}
		if (directories) {
			if (options && options.hash) {
				directories: for (const path of directories) {
					for (const immutablePath of this.immutablePathsWithSlash) {
						if (path.startsWith(immutablePath)) {
							continue directories;
						}
					}
					for (const managedPath of this.managedPathsWithSlash) {
						if (path.startsWith(managedPath)) {
							const managedItem = getManagedItem(managedPath, path);
							if (managedItem) {
								managedItems.add(managedItem);
								continue directories;
							}
						}
					}
					const cache = this._contextHashes.get(path);
					if (cache !== undefined) {
						contextHashes.set(path, cache);
					} else {
						jobs++;
						this.contextHashQueue.add(path, (err, entry) => {
							if (err) {
								if (this.logger) {
									this.logger.debug(
										`Error snapshotting context hash of ${path}: ${err}`
									);
								}
								jobError();
							} else {
								contextHashes.set(path, entry);
								jobDone();
							}
						});
					}
				}
			} else {
				directories: for (const path of directories) {
					for (const immutablePath of this.immutablePathsWithSlash) {
						if (path.startsWith(immutablePath)) {
							continue directories;
						}
					}
					for (const managedPath of this.managedPathsWithSlash) {
						if (path.startsWith(managedPath)) {
							const managedItem = getManagedItem(managedPath, path);
							if (managedItem) {
								managedItems.add(managedItem);
								continue directories;
							}
						}
					}
					const cache = this._contextTimestamps.get(path);
					if (cache !== undefined) {
						if (cache !== "ignore") {
							contextTimestamps.set(path, cache);
						}
					} else {
						jobs++;
						this.contextTimestampQueue.add(path, (err, entry) => {
							if (err) {
								if (this.logger) {
									this.logger.debug(
										`Error snapshotting context timestamp of ${path}: ${err}`
									);
								}
								jobError();
							} else {
								contextTimestamps.set(path, entry);
								jobDone();
							}
						});
					}
				}
			}
		}
		if (missing) {
			missing: for (const path of missing) {
				for (const immutablePath of this.immutablePathsWithSlash) {
					if (path.startsWith(immutablePath)) {
						continue missing;
					}
				}
				for (const managedPath of this.managedPathsWithSlash) {
					if (path.startsWith(managedPath)) {
						const managedItem = getManagedItem(managedPath, path);
						if (managedItem) {
							managedItems.add(managedItem);
							continue missing;
						}
					}
				}
				const cache = this._fileTimestamps.get(path);
				if (cache !== undefined) {
					if (cache !== "ignore") {
						missingExistance.set(path, toExistance(cache));
					}
				} else {
					jobs++;
					this.fileTimestampQueue.add(path, (err, entry) => {
						if (err) {
							if (this.logger) {
								this.logger.debug(
									`Error snapshotting missing timestamp of ${path}: ${err}`
								);
							}
							jobError();
						} else {
							missingExistance.set(path, toExistance(entry));
							jobDone();
						}
					});
				}
			}
		}
		for (const path of managedItems) {
			const cache = this._managedItems.get(path);
			if (cache !== undefined) {
				managedItemInfo.set(path, cache);
			} else {
				jobs++;
				this.managedItemQueue.add(path, (err, entry) => {
					if (err) {
						if (this.logger) {
							this.logger.debug(
								`Error snapshotting managed item ${path}: ${err}`
							);
						}
						jobError();
					} else {
						managedItemInfo.set(path, entry);
						jobDone();
					}
				});
			}
		}
		jobDone();
	}

	/**
	 * @param {Snapshot} snapshot1 a snapshot
	 * @param {Snapshot} snapshot2 a snapshot
	 * @returns {Snapshot} merged snapshot
	 */
	mergeSnapshots(snapshot1, snapshot2) {
		/** @type {Snapshot} */
		const snapshot = {};
		if (snapshot1.startTime && snapshot2.startTime)
			snapshot.startTime = Math.min(snapshot1.startTime, snapshot2.startTime);
		else if (snapshot2.startTime) snapshot.startTime = snapshot2.startTime;
		else if (snapshot1.startTime) snapshot.startTime = snapshot1.startTime;
		if (snapshot1.fileTimestamps || snapshot2.fileTimestamps) {
			snapshot.fileTimestamps = mergeMaps(
				snapshot1.fileTimestamps,
				snapshot2.fileTimestamps
			);
		}
		if (snapshot1.fileHashes || snapshot2.fileHashes) {
			snapshot.fileHashes = mergeMaps(
				snapshot1.fileHashes,
				snapshot2.fileHashes
			);
		}
		if (snapshot1.contextTimestamps || snapshot2.contextTimestamps) {
			snapshot.contextTimestamps = mergeMaps(
				snapshot1.contextTimestamps,
				snapshot2.contextTimestamps
			);
		}
		if (snapshot1.contextHashes || snapshot2.contextHashes) {
			snapshot.contextHashes = mergeMaps(
				snapshot1.contextHashes,
				snapshot2.contextHashes
			);
		}
		if (snapshot1.missingExistance || snapshot2.missingExistance) {
			snapshot.missingExistance = mergeMaps(
				snapshot1.missingExistance,
				snapshot2.missingExistance
			);
		}
		if (snapshot1.managedItemInfo || snapshot2.managedItemInfo) {
			snapshot.managedItemInfo = mergeMaps(
				snapshot1.managedItemInfo,
				snapshot2.managedItemInfo
			);
		}
		if (
			this._snapshotCache.get(snapshot1) === true &&
			this._snapshotCache.get(snapshot2) === true
		) {
			this._snapshotCache.set(snapshot, true);
		}
		return snapshot;
	}

	/**
	 * @param {Snapshot} snapshot the snapshot made
	 * @param {function(WebpackError=, boolean=): void} callback callback function
	 * @returns {void}
	 */
	checkSnapshotValid(snapshot, callback) {
		const cachedResult = this._snapshotCache.get(snapshot);
		if (cachedResult !== undefined) {
			if (typeof cachedResult === "boolean") {
				callback(null, cachedResult);
			} else {
				cachedResult.push(callback);
			}
			return;
		}
		let callbacks;
		const {
			startTime,
			fileTimestamps,
			fileHashes,
			contextTimestamps,
			contextHashes,
			missingExistance,
			managedItemInfo
		} = snapshot;
		let jobs = 1;
		const jobDone = () => {
			if (--jobs === 0) {
				this._snapshotCache.set(snapshot, true);
				callback(null, true);
			}
		};
		const invalid = () => {
			if (jobs > 0) {
				// large negative number instead of NaN or something else to keep jobs to stay a SMI (v8)
				jobs = -100000000;
				this._snapshotCache.set(snapshot, false);
				callback(null, false);
			}
		};
		const invalidWithError = (path, err) => {
			if (this._remainingLogs > 0) {
				this._log(path, `error occured: %s`, err);
			}
			invalid();
		};
		/**
		 * @param {string} path file path
		 * @param {string} current current hash
		 * @param {string} snap snapshot hash
		 * @returns {boolean} true, if ok
		 */
		const checkHash = (path, current, snap) => {
			if (current !== snap) {
				// If hash differ it's invalid
				if (this._remainingLogs > 0) {
					this._log(path, `hashes differ (%s != %s)`, current, snap);
				}
				return false;
			}
			return true;
		};
		/**
		 * @param {string} path file path
		 * @param {boolean} current current entry
		 * @param {boolean} snap entry from snapshot
		 * @returns {boolean} true, if ok
		 */
		const checkExistance = (path, current, snap) => {
			if (!current !== !snap) {
				// If existance of item differs
				// it's invalid
				if (this._remainingLogs > 0) {
					this._log(
						path,
						current ? "it didn't exist before" : "it does no longer exist"
					);
				}
				return false;
			}
			return true;
		};
		/**
		 * @param {string} path file path
		 * @param {FileSystemInfoEntry} current current entry
		 * @param {FileSystemInfoEntry} snap entry from snapshot
		 * @returns {boolean} true, if ok
		 */
		const checkFile = (path, current, snap) => {
			if (current === snap) return true;
			if (!current !== !snap) {
				// If existance of item differs
				// it's invalid
				if (this._remainingLogs > 0) {
					this._log(
						path,
						current ? "it didn't exist before" : "it does no longer exist"
					);
				}
				return false;
			}
			if (current) {
				// For existing items only
				if (current.safeTime > startTime) {
					// If a change happened after starting reading the item
					// this may no longer be valid
					if (this._remainingLogs > 0) {
						this._log(
							path,
							`it may have changed (%d) after the start time of the snapshot (%d)`,
							current.safeTime,
							startTime
						);
					}
					return false;
				}
				if (
					snap.timestamp !== undefined &&
					current.timestamp !== snap.timestamp
				) {
					// If we have a timestamp (it was a file or symlink) and it differs from current timestamp
					// it's invalid
					if (this._remainingLogs > 0) {
						this._log(
							path,
							`timestamps differ (%d != %d)`,
							current.timestamp,
							snap.timestamp
						);
					}
					return false;
				}
				if (
					snap.timestampHash !== undefined &&
					current.timestampHash !== snap.timestampHash
				) {
					// If we have a timestampHash (it was a directory) and it differs from current timestampHash
					// it's invalid
					if (this._remainingLogs > 0) {
						this._log(
							path,
							`timestamps hashes differ (%s != %s)`,
							current.timestampHash,
							snap.timestampHash
						);
					}
					return false;
				}
			}
			return true;
		};
		if (fileTimestamps) {
			for (const [path, ts] of fileTimestamps) {
				const cache = this._fileTimestamps.get(path);
				if (cache !== undefined) {
					if (cache !== "ignore" && !checkFile(path, cache, ts)) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.fileTimestampQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkFile(path, entry, ts)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		if (fileHashes) {
			for (const [path, hash] of fileHashes) {
				const cache = this._fileHashes.get(path);
				if (cache !== undefined) {
					if (cache !== "ignore" && !checkHash(path, cache, hash)) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.fileHashQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkHash(path, entry, hash)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		if (contextTimestamps && contextTimestamps.size > 0) {
			for (const [path, ts] of contextTimestamps) {
				const cache = this._contextTimestamps.get(path);
				if (cache !== undefined) {
					if (cache !== "ignore" && !checkFile(path, cache, ts)) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.contextTimestampQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkFile(path, entry, ts)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		if (contextHashes) {
			for (const [path, hash] of contextHashes) {
				const cache = this._contextHashes.get(path);
				if (cache !== undefined) {
					if (cache !== "ignore" && !checkHash(path, cache, hash)) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.contextHashQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkHash(path, entry, hash)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		if (missingExistance) {
			for (const [path, existance] of missingExistance) {
				const cache = this._fileTimestamps.get(path);
				if (cache !== undefined) {
					if (
						cache !== "ignore" &&
						!checkExistance(path, toExistance(cache), existance)
					) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.fileTimestampQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkExistance(path, toExistance(entry), existance)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		if (managedItemInfo) {
			for (const [path, info] of managedItemInfo) {
				const cache = this._managedItems.get(path);
				if (cache !== undefined) {
					if (!checkHash(path, cache, info)) {
						invalid();
						return;
					}
				} else {
					jobs++;
					this.managedItemQueue.add(path, (err, entry) => {
						if (err) return invalidWithError(path, err);
						if (!checkHash(path, entry, info)) {
							invalid();
						} else {
							jobDone();
						}
					});
				}
			}
		}
		jobDone();

		// if there was an async action
		// try to join multiple concurrent request for this snapshot
		if (jobs > 0) {
			callbacks = [callback];
			callback = (err, result) => {
				for (const callback of callbacks) callback(err, result);
			};
			this._snapshotCache.set(snapshot, callbacks);
		}
	}

	_readFileTimestamp(path, callback) {
		this.fs.stat(path, (err, stat) => {
			if (err) {
				if (err.code === "ENOENT") {
					this._fileTimestamps.set(path, null);
					return callback(null, null);
				}
				return callback(err);
			}

			let ts;
			if (stat.isDirectory()) {
				ts = {
					safeTime: 0,
					timestamp: undefined
				};
			} else {
				const mtime = +stat.mtime;

				if (mtime) applyMtime(mtime);

				ts = {
					safeTime: mtime ? mtime + FS_ACCURACY : Infinity,
					timestamp: mtime
				};
			}

			this._fileTimestamps.set(path, ts);

			callback(null, ts);
		});
	}

	_readFileHash(path, callback) {
		this.fs.readFile(path, (err, content) => {
			if (err) {
				if (err.code === "ENOENT") {
					this._fileHashes.set(path, null);
					return callback(null, null);
				}
				return callback(err);
			}

			const hash = createHash("md4");

			hash.update(content);

			const digest = /** @type {string} */ (hash.digest("hex"));

			this._fileHashes.set(path, digest);

			callback(null, digest);
		});
	}

	_readContextTimestamp(path, callback) {
		this.fs.readdir(path, (err, files) => {
			if (err) {
				if (err.code === "ENOENT") {
					this._contextTimestamps.set(path, null);
					return callback(null, null);
				}
				return callback(err);
			}
			files = files
				.map(file => file.normalize("NFC"))
				.filter(file => !/^\./.test(file))
				.sort();
			asyncLib.map(
				files,
				(file, callback) => {
					const child = join(this.fs, path, file);
					this.fs.stat(child, (err, stat) => {
						if (err) return callback(err);

						for (const immutablePath of this.immutablePathsWithSlash) {
							if (path.startsWith(immutablePath)) {
								// ignore any immutable path for timestamping
								return callback(null, null);
							}
						}
						for (const managedPath of this.managedPathsWithSlash) {
							if (path.startsWith(managedPath)) {
								const managedItem = getManagedItem(managedPath, child);
								if (managedItem) {
									// construct timestampHash from managed info
									return this.managedItemQueue.add(managedItem, (err, info) => {
										if (err) return callback(err);
										return callback(null, {
											safeTime: 0,
											timestampHash: info
										});
									});
								}
							}
						}

						if (stat.isFile()) {
							return this.getFileTimestamp(child, callback);
						}
						if (stat.isDirectory()) {
							this.contextTimestampQueue.increaseParallelism();
							this.getContextTimestamp(child, (err, tsEntry) => {
								this.contextTimestampQueue.decreaseParallelism();
								callback(err, tsEntry);
							});
							return;
						}
						callback(null, null);
					});
				},
				(err, tsEntries) => {
					if (err) return callback(err);
					const hash = createHash("md4");

					for (const file of files) hash.update(file);
					let safeTime = 0;
					for (const entry of tsEntries) {
						if (!entry) {
							hash.update("n");
							continue;
						}
						if (entry.timestamp) {
							hash.update("f");
							hash.update(`${entry.timestamp}`);
						} else if (entry.timestampHash) {
							hash.update("d");
							hash.update(`${entry.timestampHash}`);
						}
						if (entry.safeTime) {
							safeTime = Math.max(safeTime, entry.safeTime);
						}
					}

					const digest = /** @type {string} */ (hash.digest("hex"));

					const result = {
						safeTime,
						timestampHash: digest
					};

					this._contextTimestamps.set(path, result);

					callback(null, result);
				}
			);
		});
	}

	_readContextHash(path, callback) {
		this.fs.readdir(path, (err, files) => {
			if (err) {
				if (err.code === "ENOENT") {
					this._contextHashes.set(path, null);
					return callback(null, null);
				}
				return callback(err);
			}
			files = files
				.map(file => file.normalize("NFC"))
				.filter(file => !/^\./.test(file))
				.sort();
			asyncLib.map(
				files,
				(file, callback) => {
					const child = join(this.fs, path, file);
					this.fs.stat(child, (err, stat) => {
						if (err) return callback(err);

						for (const immutablePath of this.immutablePathsWithSlash) {
							if (path.startsWith(immutablePath)) {
								// ignore any immutable path for hashing
								return callback(null, "");
							}
						}
						for (const managedPath of this.managedPathsWithSlash) {
							if (path.startsWith(managedPath)) {
								const managedItem = getManagedItem(managedPath, child);
								if (managedItem) {
									// construct hash from managed info
									return this.managedItemQueue.add(managedItem, (err, info) => {
										if (err) return callback(err);
										callback(null, info || "");
									});
								}
							}
						}

						if (stat.isFile()) {
							return this.getFileHash(child, (err, hash) => {
								callback(err, hash || "");
							});
						}
						if (stat.isDirectory()) {
							this.contextHashQueue.increaseParallelism();
							this.getContextHash(child, (err, hash) => {
								this.contextHashQueue.decreaseParallelism();
								callback(err, hash || "");
							});
							return;
						}
						callback(null, "");
					});
				},
				(err, fileHashes) => {
					if (err) return callback(err);
					const hash = createHash("md4");

					for (const file of files) hash.update(file);
					for (const h of fileHashes) hash.update(h);

					const digest = /** @type {string} */ (hash.digest("hex"));

					this._contextHashes.set(path, digest);

					callback(null, digest);
				}
			);
		});
	}

	_getManagedItemDirectoryInfo(path, callback) {
		this.fs.readdir(path, (err, elements) => {
			if (err) {
				if (err.code === "ENOENT" || err.code === "ENOTDIR") {
					return callback(null, EMPTY_SET);
				}
				return callback(err);
			}
			const set = new Set(
				elements.map(element => join(this.fs, path, element))
			);
			callback(null, set);
		});
	}

	_getManagedItemInfo(path, callback) {
		const dir = dirname(this.fs, path);
		this.managedItemDirectoryQueue.add(dir, (err, elements) => {
			if (err) {
				return callback(err);
			}
			if (!elements.has(path)) {
				// file or directory doesn't exist
				this._managedItems.set(path, "missing");
				return callback(null, "missing");
			}
			// something exists
			// it may be a file or directory
			if (
				path.endsWith("node_modules") &&
				(path.endsWith("/node_modules") || path.endsWith("\\node_modules"))
			) {
				// we are only interested in existance of this special directory
				this._managedItems.set(path, "exists");
				return callback(null, "exists");
			}

			// we assume it's a directory, as files shouldn't occur in managed paths
			const packageJsonPath = join(this.fs, path, "package.json");
			this.fs.readFile(packageJsonPath, (err, content) => {
				if (err) {
					if (err.code === "ENOENT" || err.code === "ENOTDIR") {
						// no package.json or path is not a directory
						const problem = `Managed item ${path} isn't a directory or doesn't contain a package.json`;
						this.logger.warn(problem);
						return callback(new Error(problem));
					}
					return callback(err);
				}
				let data;
				try {
					data = JSON.parse(content.toString("utf-8"));
				} catch (e) {
					return callback(e);
				}
				const info = `${data.name || ""}@${data.version || ""}`;
				this._managedItems.set(path, info);
				callback(null, info);
			});
		});
	}

	getDeprecatedFileTimestamps() {
		const map = new Map();
		for (const [path, info] of this._fileTimestamps) {
			if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
		}
		return map;
	}

	getDeprecatedContextTimestamps() {
		const map = new Map();
		for (const [path, info] of this._contextTimestamps) {
			if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
		}
		return map;
	}
}

module.exports = FileSystemInfo;


text:
package it.cnr.isti.vir.similarity;

import it.cnr.isti.vir.features.AbstractFeaturesCollector;
import it.cnr.isti.vir.features.FeatureClassCollector;
import it.cnr.isti.vir.features.Permutation;
import it.cnr.isti.vir.util.PropertiesUtils;

import java.util.Properties;

public class SpearmanRho implements ISimilarity<Permutation>{

	private int l = Integer.MAX_VALUE;

	public SpearmanRho(Properties prop) {
		l = PropertiesUtils.getInt_orDefault(prop, "SpearmanRho.l", l);
	}

	public SpearmanRho() {};

	public int getMaxDist() {
		int res=0;
		for ( int i=1; i<=l; i++) {
			res+=i*i;
		}
		return res*2;
	}

	public SpearmanRho(int maxLength) {
		if ( maxLength >= 0)
			this.l =maxLength;
	}

	public void setMaxLength(int maxLength) {
		this.l =maxLength;
		if ( this.l < 0) this.l = 0;
	}

	@Override
	public final double distance(Permutation f1, Permutation f2) {
		int maxPos = l;
//		int maxPos = Math.max(f1.getOrdLength(), f2.getOrdLength());
//		if ( l!= 0 ) maxPos = Math.min(maxPos, l);

		return sfd_l(f1.getROPositions(), f2.getROPositions(), maxPos );
	}

	@Override
	public final double distance(Permutation f1, Permutation f2, double max) {

		int maxPos = l;
//		int maxPos = Math.max(f1.getOrdLength(), f2.getOrdLength());
//		if ( l!= 0 ) maxPos = Math.min(maxPos, l);

		return sfd_l(f1.getROPositions(), f2.getROPositions(), maxPos, (long) Math.ceil( max ));
	}

	@Override
	public final double distance(AbstractFeaturesCollector f1, AbstractFeaturesCollector f2 ) {
			return distance(f1.getFeature(Permutation.class), f2.getFeature(Permutation.class));
	}

	@Override
	public final double distance(AbstractFeaturesCollector f1, AbstractFeaturesCollector f2, double max ) {
		return distance(f1.getFeature(Permutation.class), f2.getFeature(Permutation.class), max);
	}

	@Override
	public long getDistCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public FeatureClassCollector getRequestedFeaturesClasses() {
		// TODO Auto-generated method stub
		return new FeatureClassCollector( Permutation.class );
	}

//	public static long sfd(int[] pos1, int[] pos2) {
//		long sum = 0;
//		for ( int i=0; i<pos1.length; i++) {
//			long temp = pos1[i] - pos2[i];
//			sum += temp*temp;
//		}
//		return sum;
//	}
//
//	public static long sfd(int[] pos1, int[] pos2, long max) {
//		long sum = 0;
//		for ( int i=0; i<pos1.length; i++) {
//			long temp = pos1[i] - pos2[i];
//			sum += temp*temp;
//			if ( sum > max ) return -sum;
//		}
//		return sum;
//	}

	/**
	 * @param obj1
	 * @param obj2
	 * @param permLength max permutation length
	 * @return
	 */
	public static final double sfd_l(int[] pos1, int[] pos2, int maxPos ) {

		return sfd_l(pos1, pos2, maxPos, Long.MAX_VALUE);
	}

	/**
	 * @param obj1
	 * @param obj2
	 * @param max
	 * @param permLength max permutation length
	 * @return
	 */
	public static final double  sfd_l(int[] pos1, int[] pos2, long maxPos, long max ) {

		long sum = 0;
		for ( int i=0; i<pos1.length; i++) {
			long temp =
					Math.min( pos1[i], maxPos ) -
					Math.min( pos2[i], maxPos );

			sum += temp*temp;
			if ( sum > max ) return -sum;
		}
		return sum;
	}

	public String getStatsString() { return ""; };

}


text:
using System;

/// <summary>
/// Char.IsLower(Char)
/// Indicates whether the specified Unicode character is categorized as a lowercase letter.
/// </summary>
public class CharIsLower
{
    public static int Main()
    {
        CharIsLower testObj = new CharIsLower();

        TestLibrary.TestFramework.BeginTestCase("for method: Char.IsLower(Char)");
        if (testObj.RunTests())
        {
            TestLibrary.TestFramework.EndTestCase();
            TestLibrary.TestFramework.LogInformation("PASS");
            return 100;
        }
        else
        {
            TestLibrary.TestFramework.EndTestCase();
            TestLibrary.TestFramework.LogInformation("FAIL");
            return 0;
        }
    }

    public bool RunTests()
    {
        bool retVal = true;

        TestLibrary.TestFramework.LogInformation("[Positive]");
        retVal = PosTest1() && retVal;
        retVal = PosTest2() && retVal;
        retVal = PosTest3() && retVal;

        return retVal;
    }
    #region Positive tests
    public bool PosTest1()
    {
        //Generate the character for validate
        char ch = 'a';

        return this.DoTest("PosTest1: Lowercase letter character",
                                  "P001", "001", "002", ch, true);
    }

    public bool PosTest2()
    {
        //Generate a non  character for validate
        char ch = 'A';
        return this.DoTest("PosTest2: Uppercase letter character.",
                                  "P002", "003", "004", ch, false);
    }

    public bool PosTest3()
    {
        //Generate a non  character for validate
        char ch = TestLibrary.Generator.GetCharNumber(-55);
        return this.DoTest("PosTest3: Non letter character.",
                                  "P003", "005", "006", ch, false);
    }
    #endregion

    #region Helper method for positive tests
    private bool DoTest(string testDesc,
                                string testId,
                                string errorNum1,
                                string errorNum2,
                                char ch,
                                bool expectedResult)
    {
        bool retVal = true;
        string errorDesc;

        TestLibrary.TestFramework.BeginScenario(testDesc);
        try
        {
            bool actualResult = char.IsLower(ch);
            if (expectedResult != actualResult)
            {
                if (expectedResult)
                {
                    errorDesc = string.Format("Character \\u{0:x} should belong to lowercase letter characters.", (int)ch);
                }
                else
                {
                    errorDesc = string.Format("Character \\u{0:x} does not belong to lowercase letter characters.", (int)ch);
                }

                TestLibrary.TestFramework.LogError(errorNum1+ " TestId-" + testId, errorDesc);
                retVal = false;
            }
        }
        catch (Exception e)
        {
            errorDesc = "Unexpected exception: " + e;
            errorDesc += string.Format("\nCharacter is \\u{0:x}", ch);
            TestLibrary.TestFramework.LogError(errorNum2 + " TestId-" + testId, errorDesc);
            retVal = false;
        }

        return retVal;
    }
    #endregion
}


text:
package au.com.scds.dss.dex;

import org.joda.time.LocalDate;

public class LocalDateAdapter {

	public static LocalDate unmarshal(String v) throws Exception {
		return new LocalDate(v);
	}

	public static String marshal(LocalDate v) throws Exception {
		return v.toString();
	}
}


text:
package org.apache.drill.exec.physical.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.List;

import mockit.Injectable;
import mockit.NonStrictExpectations;

import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.expression.ExpressionPosition;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.util.FileUtils;
import org.apache.drill.exec.client.DrillClient;
import org.apache.drill.exec.compile.CodeCompiler;
import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
import org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.Float4Holder;
import org.apache.drill.exec.expr.holders.Float8Holder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.VarBinaryHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.drill.exec.memory.TopLevelAllocator;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.PhysicalPlan;
import org.apache.drill.exec.physical.base.FragmentRoot;
import org.apache.drill.exec.planner.PhysicalPlanReader;
import org.apache.drill.exec.pop.PopUnitTestBase;
import org.apache.drill.exec.proto.BitControl.PlanFragment;
import org.apache.drill.exec.proto.CoordinationProtos;
import org.apache.drill.exec.record.RecordBatchLoader;
import org.apache.drill.exec.record.VectorAccessible;
import org.apache.drill.exec.record.VectorWrapper;
import org.apache.drill.exec.rpc.user.QueryResultBatch;
import org.apache.drill.exec.rpc.user.UserServer;
import org.apache.drill.exec.server.Drillbit;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.server.RemoteServiceSet;
import org.apache.drill.exec.vector.BigIntVector;
import org.apache.drill.exec.vector.Float4Vector;
import org.apache.drill.exec.vector.Float8Vector;
import org.apache.drill.exec.vector.IntVector;
import org.apache.drill.exec.vector.VarBinaryVector;
import org.apache.drill.exec.vector.VarCharVector;
import org.junit.Test;

import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Charsets;
import com.google.common.io.Files;

public class TestCastFunctions extends PopUnitTestBase{
  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestSimpleFunctions.class);

  DrillConfig c = DrillConfig.create();

  @Test
  // cast to bigint.
  public void testCastBigInt(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();

    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastBigInt.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      BigIntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), BigIntVector.class);
      BigIntVector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          BigIntHolder holder0 = new BigIntHolder();
          a0.get(i, holder0);
          assertEquals(1256, holder0.value);
          ++count;

      }
      assertEquals(5, count);
    }

    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //cast to int
  public void testCastInt(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();

    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastInt.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      IntVector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast", ExpressionPosition.UNKNOWN), IntVector.class);
      IntVector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          IntHolder holder0 = new IntHolder();
          a0.get(i, holder0);
          assertEquals(1256, holder0.value);
          ++count;

      }
      assertEquals(5, count);
    }

    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //cast to float4
  public void testCastFloat4(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{
    final BufferAllocator allocator = new TopLevelAllocator();
    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastFloat4.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      Float4Vector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast2", ExpressionPosition.UNKNOWN), Float4Vector.class);
      Float4Vector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          Float4Holder holder0 = new Float4Holder();
          a0.get(i, holder0);
          assertEquals(12.56, holder0.value, 0.001);
          ++count;

      }
      assertEquals(5, count);
    }

    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //cast to float8
  public void testCastFloat8(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();
    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastFloat8.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      Float8Vector c0 = exec.getValueVectorById(new SchemaPath("varchar_cast2", ExpressionPosition.UNKNOWN), Float8Vector.class);
      Float8Vector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          Float8Holder holder0 = new Float8Holder();
          a0.get(i, holder0);
          assertEquals(12.56, holder0.value, 0.001);
          ++count;

      }
      assertEquals(5, count);
    }

    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //cast to varchar(length)
  public void testCastVarChar(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();
    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastVarChar.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      VarCharVector c0 = exec.getValueVectorById(new SchemaPath("int_lit_cast", ExpressionPosition.UNKNOWN), VarCharVector.class);
      VarCharVector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          VarCharHolder holder0 = new VarCharHolder();
          a0.get(i, holder0);
          assertEquals("123", StringFunctionHelpers.toStringFromUTF8(holder0.start, holder0.end, holder0.buffer));
          ++count;

      }
      assertEquals(5, count);
    }

    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //cast to varbinary(length)
  public void testCastVarBinary(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();

    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastVarBinary.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      VarBinaryVector c0 = exec.getValueVectorById(new SchemaPath("int_lit_cast", ExpressionPosition.UNKNOWN), VarBinaryVector.class);
      VarBinaryVector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          VarBinaryHolder holder0 = new VarBinaryHolder();
          a0.get(i, holder0);
          assertEquals("123", StringFunctionHelpers.toStringFromUTF8(holder0.start, holder0.end, holder0.buffer));
          ++count;

      }
      assertEquals(5, count);
    }
    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }
    assertTrue(!context.isFailed());
  }

  @Test
  //nested: cast is nested in another cast, or another function.
  public void testCastNested(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();
    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastNested.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
      IntVector c0 = exec.getValueVectorById(new SchemaPath("add_cast", ExpressionPosition.UNKNOWN),IntVector.class);
      IntVector.Accessor a0;
      a0 = c0.getAccessor();

      int count = 0;
      for(int i = 0; i < c0.getAccessor().getValueCount(); i++){
          IntHolder holder0 = new IntHolder();
          a0.get(i, holder0);
          assertEquals(300, holder0.value);
          ++count;

      }
      assertEquals(5, count);
    }
    exec.stop();

    context.close();
    allocator.close();

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }

    assertTrue(!context.isFailed());
  }

  @Test(expected = NumberFormatException.class)
  public void testCastNumException(@Injectable final DrillbitContext bitContext,
                            @Injectable UserServer.UserClientConnection connection) throws Throwable{

    final BufferAllocator allocator = new TopLevelAllocator();

    new NonStrictExpectations(){{
      bitContext.getMetrics(); result = new MetricRegistry();
      bitContext.getAllocator(); result = allocator;
      bitContext.getConfig(); result = c;
      bitContext.getCompiler(); result = CodeCompiler.getTestCompiler(c);
      bitContext.getOperatorCreatorRegistry(); result = new OperatorCreatorRegistry(c);
    }};

    PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
    PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastNumException.json"), Charsets.UTF_8));
    FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
    FragmentContext context = new FragmentContext(bitContext, PlanFragment.getDefaultInstance(), connection, registry);
    SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));

    while(exec.next()){
    }

    exec.stop();

    context.close();
    allocator.close();

    assertTrue(context.isFailed());

    if(context.getFailureCause() != null){
      throw context.getFailureCause();
    }

  }

  @Test
  public void testCastFromNullablCol() throws Throwable {
    RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();

    try(Drillbit bit = new Drillbit(CONFIG, serviceSet);
        DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
      bit.run();

      client.connect();
      List<QueryResultBatch> results = client.runQuery(org.apache.drill.exec.proto.UserBitShared.QueryType.PHYSICAL,
          Files.toString(FileUtils.getResourceAsFile("/functions/cast/testCastVarCharNull.json"), Charsets.UTF_8).replace("#{TEST_FILE}", "/jsoninput/input1.json"));

      QueryResultBatch batch = results.get(0);

      RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator());
      batchLoader.load(batch.getHeader().getDef(), batch.getData());

      Object [][] result = getRunResult(batchLoader);

      Object [][] expected = new Object[2][2];

      expected[0][0] = new String("2001");
      expected[0][1] = new String("1.2");

      expected[1][0] = new String("-2002");
      expected[1][1] = new String("-1.2");

      assertEquals(result.length, expected.length);
      assertEquals(result[0].length, expected[0].length);

      for (int i = 0; i<result.length; i++ ) {
        for (int j = 0; j<result[0].length; j++) {
          assertEquals(String.format("Column %s at row %s have wrong result",  j, i), result[i][j].toString(), expected[i][j]);
        }
      }
      batchLoader.clear();
      for(QueryResultBatch b : results){
        b.release();
      }

    }
  }

  private Object[][] getRunResult(VectorAccessible va) {
    int size = 0;
    for (VectorWrapper v : va) {
      size++;
    }

    Object[][] res = new Object [va.getRecordCount()][size];
    for (int j = 0; j < va.getRecordCount(); j++) {
      int i = 0;
      for (VectorWrapper v : va) {
        Object o =  v.getValueVector().getAccessor().getObject(j);
        if (o instanceof byte[]) {
          res[j][i++] =  new String((byte[]) o);
        } else {
          res[j][i++] = o;
        }
      }
    }
    return res;
 }

}