text:
import os
import urllib
import json
import pkgutil
import tarfile
import tempfile
from time import sleep, time
from StringIO import StringIO

import jinja2
import fabric
import fabric.api

from cloudify import ctx
from cloudify.decorators import operation
from cloudify.exceptions import NonRecoverableError
from cloudify_cli import utils

REST_PORT = 80

# internal runtime properties - used by the CLI to store local context
PROVIDER_RUNTIME_PROPERTY = 'provider'
MANAGER_IP_RUNTIME_PROPERTY = 'manager_ip'
MANAGER_USER_RUNTIME_PROPERTY = 'manager_user'
MANAGER_KEY_PATH_RUNTIME_PROPERTY = 'manager_key_path'
DEFAULT_REMOTE_AGENT_KEY_PATH = '~/.ssh/agent_key.pem'

lgr = None

@operation
def creation_validation(cloudify_packages, **kwargs):
    if not isinstance(cloudify_packages, dict):
        raise NonRecoverableError('"cloudify_packages" must be a '
                                  'dictionary property')
    docker_packages = cloudify_packages.get('docker')

    if not docker_packages or not isinstance(docker_packages, dict):
        raise NonRecoverableError(
            '"docker" must be a non-empty dictionary property under '
            '"cloudify_packages"')

    packages_urls = docker_packages.values()
    agent_packages = cloudify_packages.get('agents', {})
    if not isinstance(agent_packages, dict):
        raise NonRecoverableError('"cloudify_packages.agents" must be a '
                                  'dictionary property')

    packages_urls.extend(agent_packages.values())
    for package_url in packages_urls:
        _validate_package_url_accessible(package_url)

def stop_manager_container(docker_path=None, use_sudo=True):
    if not docker_path:
        docker_path = 'docker'
    command = '{0} stop cfy'.format(docker_path)
    if use_sudo:
        command = 'sudo {0}'.format(command)
    _run_command(command)

def stop_docker_service(docker_service_stop_command=None, use_sudo=True):

    if not docker_service_stop_command:
        docker_service_stop_command = 'service docker stop'
    if use_sudo:
        docker_service_stop_command = 'sudo {0}'\
            .format(docker_service_stop_command)

    # this is needed so that docker will stop using the
    # /var/lib/docker directory, which might be mounted on a
    # volume.
    _run_command(docker_service_stop_command)

def _install_docker_if_required(docker_path, use_sudo,
                                docker_service_start_command):
    # CFY-1627 - plugin dependency should be removed.
    from fabric_plugin.tasks import FabricTaskError

    if not docker_path:
        docker_path = 'docker'
    docker_installed = _is_docker_installed(docker_path, use_sudo)
    if not docker_installed:
        try:
            distro_info = get_machine_distro()
        except FabricTaskError as e:
            err = 'failed getting platform distro. error is: {0}'\
                  .format(str(e))
            lgr.error(err)
            raise
        if 'trusty' not in distro_info:
            err = ('bootstrap using the Docker Cloudify image requires either '
                   'running on \'Ubuntu 14.04 trusty\' or having Docker '
                   'pre-installed on the remote machine.')
            lgr.error(err)
            raise NonRecoverableError(err)

        try:
            lgr.info('installing Docker')
            _run_command('curl -sSL https://get.docker.com/ubuntu/ | sudo sh')
        except FabricTaskError:
            err = 'failed installing docker on remote host.'
            lgr.error(err)
            raise
    else:
        lgr.debug('\"docker\" is already installed.')
        try:
            info_command = '{0} info'.format(docker_path)
            if use_sudo:
                info_command = 'sudo {0}'.format(info_command)
            _run_command(info_command)
        except BaseException as e:
            lgr.debug('Failed retrieving docker info: {0}'.format(str(e)))
            lgr.debug('Trying to start docker service')
            if not docker_service_start_command:
                docker_service_start_command = 'service docker start'
            if use_sudo:
                docker_service_start_command = 'sudo {0}'\
                    .format(docker_service_start_command)
            _run_command(docker_service_start_command)

    if use_sudo:
        docker_exec_command = '{0} {1}'.format('sudo', docker_path)
    else:
        docker_exec_command = docker_path
    return docker_exec_command

def bootstrap_docker(cloudify_packages, docker_path=None, use_sudo=True,
                     agent_local_key_path=None, agent_remote_key_path=None,
                     manager_private_ip=None, provider_context=None,
                     docker_service_start_command=None, privileged=False):
    if agent_remote_key_path is None:
        agent_remote_key_path = DEFAULT_REMOTE_AGENT_KEY_PATH

    if 'containers_started' in ctx.instance.runtime_properties:
        try:
            recover_docker(docker_path, use_sudo, docker_service_start_command)
            # the runtime property specifying the manager openstack instance id
            # has changed, so we need to update the manager deployment in the
            # provider context.
            _update_manager_deployment()
        except Exception:
            # recovery failed, however runtime properties may have still
            # changed. update the local manager deployment only
            _update_manager_deployment(local_only=True)
            raise

        return
    # CFY-1627 - plugin dependency should be removed.
    from fabric_plugin.tasks import FabricTaskError
    global lgr
    lgr = ctx.logger

    manager_ip = fabric.api.env.host_string
    lgr.info('initializing manager on the machine at {0}'.format(manager_ip))

    def post_bootstrap_actions(wait_for_services_timeout=180):
        lgr.info('waiting for cloudify management services to start')
        started = _wait_for_management(manager_ip,
                                       timeout=wait_for_services_timeout)
        if not started:
            err = 'failed waiting for cloudify management services to start.'
            lgr.info(err)
            raise NonRecoverableError(err)
        _set_manager_endpoint_data()
        ctx.instance.runtime_properties['containers_started'] = 'True'
        try:
            _upload_provider_context(agent_remote_key_path, provider_context)
        except:
            del ctx.instance.runtime_properties['containers_started']
            raise
        return True

    if ctx.operation.retry_number > 0:
        return post_bootstrap_actions(wait_for_services_timeout=15)

    docker_exec_command = _install_docker_if_required(
        docker_path,
        use_sudo,
        docker_service_start_command)

    data_container_name = 'data'
    cfy_container_name = 'cfy'
    if _container_exists(docker_exec_command, data_container_name) or \
            _container_exists(docker_exec_command, cfy_container_name):
        err = 'a container instance with name {0}/{1} already exists.'\
              .format(data_container_name, cfy_container_name)
        raise NonRecoverableError(err)

    docker_image_url = cloudify_packages.get('docker', {}).get('docker_url')
    if not docker_image_url:
        raise NonRecoverableError('no docker URL found in packages')
    try:
        lgr.info('importing cloudify-manager docker image from {0}'
                 .format(docker_image_url))
        _run_command('{0} import {1} cloudify'
                     .format(docker_exec_command, docker_image_url))
    except FabricTaskError as e:
        err = 'failed importing cloudify docker image from {0}. reason:{1}' \
              .format(docker_image_url, str(e))
        lgr.error(err)
        raise NonRecoverableError(err)

    cloudify_config = ctx.node.properties['cloudify']
    security_config = cloudify_config.get('security', {})
    security_config_path = _handle_security_configuration(security_config)

    cfy_management_options = ('-t '
                              '--volumes-from data '
                              '--privileged={0} '
                              '-p 80:80 '
                              '-p 5555:5555 '
                              '-p 5672:5672 '
                              '-p 53229:53229 '
                              '-p 8100:8100 '
                              '-p 8101:8101 '
                              '-p 9200:9200 '
                              '-p 8086:8086 '
                              '-e MANAGEMENT_IP={1} '
                              '-e MANAGER_REST_SECURITY_CONFIG_PATH={2} '
                              '--restart=always '
                              '-d '
                              'cloudify '
                              '/sbin/my_init'
                              .format(privileged,
                                      manager_private_ip or
                                      ctx.instance.host_ip,
                                      security_config_path))

    agent_packages = cloudify_packages.get('agents')
    if agent_packages:
        # compose agent installation command.
        data_container_work_dir = '/tmp/work_dir'
        agents_dest_dir = '/opt/manager/resources/packages'
        agent_packages_install_cmd = \
            _get_install_agent_pkgs_cmd(agent_packages,
                                        data_container_work_dir,
                                        agents_dest_dir)
        agent_pkgs_mount_options = '-v {0} -w {1} ' \
                                   .format(agents_dest_dir,
                                           data_container_work_dir)
    else:
        lgr.info('no agent packages were provided')
        agent_packages_install_cmd = 'echo no agent packages provided'
        agent_pkgs_mount_options = ''

    # command to copy host VM home dir files into the data container's home.
    backup_vm_files_cmd, home_dir_mount_path = _get_backup_files_cmd()
    # copy agent to host VM. the data container will mount the host VM's
    # home-dir so that all files will be backed up inside the data container.
    _copy_agent_key(agent_local_key_path, agent_remote_key_path)

    install_plugins_cmd = _handle_plugins_and_create_install_cmd(
        cloudify_config.get('plugins', {}))

    data_container_start_cmd = '{0} && {1} && {2} && echo Data-only container'\
                               .format(agent_packages_install_cmd,
                                       backup_vm_files_cmd,
                                       install_plugins_cmd)
    data_container_options = ('-t '
                              '{0} '
                              '-v ~/:{1} '
                              '-v /root '
                              '--privileged={2} '
                              '-v /etc/init.d '
                              '-v /etc/default '
                              '-v /opt/manager/resources '
                              '-v /opt/manager/env '
                              '-v /etc/service/riemann '
                              '-v /etc/service/elasticsearch/data '
                              '-v /etc/service/elasticsearch/logs '
                              '-v /opt/influxdb/shared/data '
                              '-v /var/log/cloudify '
                              'cloudify sh -c \'{3}\''
                              .format(agent_pkgs_mount_options,
                                      home_dir_mount_path,
                                      privileged,
                                      data_container_start_cmd))

    try:
        lgr.info('starting a new cloudify data container')
        _run_docker_container(docker_exec_command, data_container_options,
                              data_container_name)
        lgr.info('starting a new cloudify mgmt docker services container')
        _run_docker_container(docker_exec_command, cfy_management_options,
                              cfy_container_name, attempts_on_corrupt=5)
    except FabricTaskError as e:
        err = 'failed running cloudify docker container. ' \
              'error is {0}'.format(str(e))
        lgr.error(err)
        raise NonRecoverableError(err)

    return post_bootstrap_actions()

def recover_docker(docker_path=None, use_sudo=True,
                   docker_service_start_command=None):
    global lgr
    lgr = ctx.logger

    manager_ip = fabric.api.env.host_string
    lgr.info('initializing manager on the machine at {0}'.format(manager_ip))
    _install_docker_if_required(docker_path, use_sudo,
                                docker_service_start_command)

    lgr.info('waiting for cloudify management services to restart')
    started = _wait_for_management(manager_ip, timeout=180)
    _recover_deployments(docker_path, use_sudo)
    if not started:
        err = 'failed waiting for cloudify management services to restart.'
        lgr.info(err)
        raise NonRecoverableError(err)

def _recover_deployments(docker_path=None, use_sudo=True):

    ctx.logger.info('Recovering deployments...')
    script_relpath = ctx.instance.runtime_properties.get(
        'recovery_script_relpath')
    if not script_relpath:
        raise NonRecoverableError('Cannot recover deployments. No recovery '
                                  'script specified.')
    script = ctx.download_resource(
        script_relpath)
    fabric.api.put(script, '~/recover_deployments.sh')
    _run_command('chmod +x ~/recover_deployments.sh')
    _run_command_in_cfy('/tmp/home/recover_deployments.sh',
                        docker_path=docker_path,
                        use_sudo=use_sudo)

def _get_backup_files_cmd():
    container_tmp_homedir_path = '/tmp/home'
    backup_homedir_cmd = 'cp -rf {0}/. /root' \
                         .format(container_tmp_homedir_path)
    return backup_homedir_cmd, container_tmp_homedir_path

def _get_install_agent_pkgs_cmd(agent_packages,
                                agents_pkg_path,
                                agents_dest_dir):
    download_agents_cmd = ''
    install_agents_cmd = ''
    for agent_name, agent_url in agent_packages.items():
        download_agents_cmd += 'curl -O {0}{1} ' \
                               .format(agent_url, ' && ')

    install_agents_cmd += 'rm -rf {0}/* && dpkg -i {1}/*.deb' \
                          .format(agents_dest_dir,
                                  agents_pkg_path)

    return '{0} {1}'.format(download_agents_cmd, install_agents_cmd)

def _handle_plugins_and_create_install_cmd(plugins):
    # no plugins configured, run a stub 'true' command
    if not plugins:
        return 'true'

    cloudify_plugins = 'cloudify/plugins'
    install_plugins = 'install_plugins.sh'

    # create location to place tar-gzipped plugins in
    _run_command('mkdir -p ~/{0}'.format(cloudify_plugins))

    # for each plugin tha is included in the blueprint, tar-gzip it
    # and place it in the plugins dir on the host
    for name, plugin in plugins.items():
        source = plugin['source']
        if source.split('://')[0] in ['http', 'https']:
            continue

        # temporary workaround to resolve absolute file path
        # to installed plugin using internal local workflows storage
        # information
        plugin_path = os.path.join(ctx._endpoint.storage.resources_root,
                                   source)

        with tempfile.TemporaryFile() as fileobj:
            with tarfile.open(fileobj=fileobj, mode='w:gz') as tar:
                tar.add(plugin_path, arcname=name)
            fileobj.seek(0)
            tar_remote_path = '{0}/{1}.tar.gz'.format(cloudify_plugins, name)
            fabric.api.put(fileobj, '~/{0}'.format(tar_remote_path))
            plugin['source'] = 'file:///root/{0}'.format(tar_remote_path)

    # render script template and copy it to host's home dir
    script_template = pkgutil.get_data('cloudify_cli.bootstrap.resources',
                                       'install_plugins.sh.template')
    script = jinja2.Template(script_template).render(plugins=plugins)
    fabric.api.put(StringIO(script), '~/{0}'.format(install_plugins))
    _run_command('chmod +x ~/{0}'.format(install_plugins))
    # path to script on container after host's home has been copied to
    # container's home
    return '/root/{0}'.format(install_plugins)

def _is_docker_installed(docker_path, use_sudo):
    """
    Returns true if docker run command exists
    :param docker_path: the docker path
    :param use_sudo: use sudo to run docker
    :return: True if docker run command exists, False otherwise
    """
    # CFY-1627 - plugin dependency should be removed.
    from fabric_plugin.tasks import FabricTaskError
    try:
        if use_sudo:
            out = fabric.api.run('sudo which {0}'.format(docker_path))
        else:
            out = fabric.api.run('which {0}'.format(docker_path))
        if not out:
            return False
        return True
    except FabricTaskError:
        return False

def _wait_for_management(ip, timeout, port=REST_PORT):
    """ Wait for url to become available
        :param ip: the manager IP
        :param timeout: in seconds
        :param port: port used by the rest service.
        :return: True of False
    """
    validation_url = 'http://{0}:{1}/version'.format(ip, port)

    end = time() + timeout

    while end - time() >= 0:
        try:
            status = urllib.urlopen(validation_url).getcode()
            if status == 200:
                return True

        except IOError as e:
            lgr.debug('error waiting for {0}. reason: {1}'
                      .format(validation_url, e.message))
        sleep(5)

    return False

def _set_manager_endpoint_data():
    ctx.instance.runtime_properties[MANAGER_IP_RUNTIME_PROPERTY] = \
        fabric.api.env.host_string
    ctx.instance.runtime_properties[MANAGER_USER_RUNTIME_PROPERTY] = \
        fabric.api.env.user
    ctx.instance.runtime_properties[MANAGER_KEY_PATH_RUNTIME_PROPERTY] = \
        fabric.api.env.key_filename

def _handle_security_configuration(blueprint_security_config):
    remote_security_config_path = '~/rest-security-config.json'
    container_security_config_path = '/root/rest-security-config.json'
    secured_server = blueprint_security_config.get('enabled', False)
    securest_userstore_driver = blueprint_security_config.get(
        'userstore_driver', {})
    securest_authentication_providers = blueprint_security_config.get(
        'authentication_providers', [])
    auth_token_generator = blueprint_security_config.get(
        'auth_token_generator', {})
    # TODO: this is the place to provide initial validation for the security
    # related configuration parts.
    security_config = dict(
        secured_server=secured_server,
        securest_userstore_driver=securest_userstore_driver,
        securest_authentication_providers=securest_authentication_providers,
        auth_token_generator=auth_token_generator)
    security_config_file_obj = StringIO()
    json.dump(security_config, security_config_file_obj)
    fabric.api.put(security_config_file_obj, remote_security_config_path)
    return container_security_config_path

def _copy_agent_key(agent_local_key_path, agent_remote_key_path):
    if not agent_local_key_path:
        return
    agent_local_key_path = os.path.expanduser(agent_local_key_path)
    ctx.logger.info(
        'Copying agent key to management machine: {0} -> {1}'.format(
            agent_local_key_path, agent_remote_key_path))
    fabric.api.put(agent_local_key_path, agent_remote_key_path)

def _update_manager_deployment(local_only=False):

    # get the current provider from the runtime property set on bootstrap
    provider_context = ctx.instance.runtime_properties[
        PROVIDER_RUNTIME_PROPERTY]

    # construct new manager deployment
    provider_context['cloudify'][
        'manager_deployment'] = _dump_manager_deployment()

    # update locally
    ctx.instance.runtime_properties[
        PROVIDER_RUNTIME_PROPERTY] = provider_context
    with utils.update_wd_settings() as wd_settings:
        wd_settings.set_provider_context(provider_context)

    if not local_only:
        # update on server
        rest_client = utils.get_rest_client()
        rest_client.manager.update_context('provider', provider_context)

def _upload_provider_context(remote_agents_private_key_path,
                             provider_context=None):
    ctx.logger.info('updating provider context on management server...')
    provider_context = provider_context or dict()
    cloudify_configuration = ctx.node.properties['cloudify']
    cloudify_configuration['cloudify_agent']['agent_key_path'] = \
        remote_agents_private_key_path
    provider_context['cloudify'] = cloudify_configuration
    ctx.instance.runtime_properties[PROVIDER_RUNTIME_PROPERTY] = \
        provider_context

    # 'manager_deployment' is used when running 'cfy use ...'
    # and then calling teardown or recover. Anyway, this code will only live
    # until we implement the fuller feature of uploading manager blueprint
    # deployments to the manager.
    cloudify_configuration['manager_deployment'] = _dump_manager_deployment()

    remote_provider_context_file = '~/provider-context.json'
    container_provider_context_file = '/tmp/home/provider-context.json'
    provider_context_json_file = StringIO()
    full_provider_context = {
        'name': 'provider',
        'context': provider_context
    }
    json.dump(full_provider_context, provider_context_json_file)

    # placing provider context file in the manager's host
    fabric.api.put(provider_context_json_file,
                   remote_provider_context_file)

    upload_provider_context_cmd = \
        'curl --fail -XPOST localhost:8101/provider/context -H ' \
        '"Content-Type: application/json" -d @{0}'.format(
            container_provider_context_file)

    # uploading the provider context to the REST service
    _run_command_in_cfy(upload_provider_context_cmd, terminal=True)

def _run_command(command, shell_escape=None):
    return fabric.api.run(command, shell_escape=shell_escape)

def _run_command_in_cfy(command, docker_path=None, use_sudo=True,
                        terminal=False):
    if not docker_path:
        docker_path = 'docker'
    exec_command = 'exec -t' if terminal else 'exec'
    full_command = '{0} {1} cfy {2}'.format(
        docker_path, exec_command, command)
    if use_sudo:
        full_command = 'sudo {0}'.format(full_command)
    _run_command(full_command)

def _container_exists(docker_exec_command, container_name):
    # CFY-1627 - plugin dependency should be removed.
    from fabric_plugin.tasks import FabricTaskError
    try:
        inspect_command = '{0} inspect {1}'.format(docker_exec_command,
                                                   container_name)
        _run_command(inspect_command)
        return True
    except FabricTaskError:
        return False

def _run_docker_container(docker_exec_command, container_options,
                          container_name, attempts_on_corrupt=1):
    # CFY-1627 - plugin dependency should be removed.
    from fabric_plugin.tasks import FabricTaskError
    run_cmd = '{0} run --name {1} {2}'\
              .format(docker_exec_command, container_name, container_options)
    for i in range(0, attempts_on_corrupt):
        try:
            lgr.debug('starting docker container {0}'.format(container_name))
            return _run_command(run_cmd)
        except FabricTaskError:
            lgr.debug('container execution failed on attempt {0}/{1}'
                      .format(i + 1, attempts_on_corrupt))
            container_exists = _container_exists(docker_exec_command,
                                                 container_name)
            if container_exists:
                lgr.debug('container {0} started in a corrupt state. '
                          'removing container.'.format(container_name))
                rm_container_cmd = '{0} rm -f {1}'.format(docker_exec_command,
                                                          container_name)
                _run_command(rm_container_cmd)
            if not container_exists or i + 1 == attempts_on_corrupt:
                lgr.error('failed executing command: {0}'.format(run_cmd))
                raise
            sleep(2)

def get_machine_distro():
    return _run_command('python -c "import platform, json, sys; '
                        'sys.stdout.write(\'{0}\\n\''
                        '.format(json.dumps(platform.dist())))"')

def _validate_package_url_accessible(package_url):
    ctx.logger.debug('checking whether url {0} is accessible'.format(
        package_url))
    status = urllib.urlopen(package_url).getcode()
    if not status == 200:
        err = ('url {0} is not accessible'.format(package_url))
        ctx.logger.error('VALIDATION ERROR: ' + err)
        raise NonRecoverableError(err)
    ctx.logger.debug('OK: url {0} is accessible'.format(package_url))

# temp workaround to enable teardown and recovery from different machines
def _dump_manager_deployment():
    from cloudify_cli.bootstrap.bootstrap import dump_manager_deployment
    from cloudify_cli.bootstrap.bootstrap import load_env

    # explicitly write the manager node instance id to local storage
    env = load_env('manager')
    with env.storage.payload() as payload:
        payload['manager_node_instance_id'] = ctx.instance.id

    # explicitly flush runtime properties to local storage
    ctx.instance.update()
    return dump_manager_deployment()

redpajama_set_name: RedPajamaGithub


text:
<?hh //strict

/**
 * This file is part of hhpack\typechecker package.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace HHPack\TypeChecker;

use HHPack\TypeChecker\Check\Result;
use HHPack\TypeChecker\Check\TypeCheckReportDecoder;
use HHPack\TypeChecker\Coverage\ResultNode;
use HHPack\TypeChecker\Coverage\CoverageReportDecoder;
use HHPack\Process;
use HHPack\Process\ExecOptions;
use RuntimeException;

final class TypeCheckerClient implements ClientBehavior
{

    const PROGRAM = 'hh_client';

    public function __construct(
        private string $cwd = (string) getcwd()
    )
    {
    }

    public async function version() : Awaitable<version>
    {
        $options = new ExecOptions($this->cwd);

        $result = await Process\exec( $this->command('', [ '--version' ]), $options );
        $version = (string) $result->stdout();

        return trim($version);
    }

    public async function init() : Awaitable<configurationPath>
    {
        $path = realpath($this->cwd) . '/.hhconfig';

        if (touch($path) === false) {
            throw new RuntimeException('Failed to generate .hhconfig');
        }

        return $path;
    }

    public async function start() : Awaitable<void>
    {
        $options = new ExecOptions($this->cwd);
        await Process\exec( $this->command('start'), $options );
    }

    public async function stop() : Awaitable<void>
    {
        $options = new ExecOptions($this->cwd);
        await Process\exec( $this->command('stop'), $options );
    }

    public async function restart() : Awaitable<void>
    {
        $options = new ExecOptions($this->cwd);
        await Process\exec( $this->command('restart'), $options );
    }

    public async function check() : Awaitable<Result>
    {
        $options = new ExecOptions($this->cwd);
        $result = await Process\exec( $this->command('check', [ '--json' ]), $options);

        $decoder = new TypeCheckReportDecoder();
        return $decoder->decode((string) $result->stderr());
    }

    public async function coverage() : Awaitable<ResultNode>
    {
        $options = new ExecOptions($this->cwd);
        $cmd = $this->command('check', [ '--json', '--coverage', $this->cwd ]);

        $result = await Process\exec($cmd, $options);

        $decoder = new CoverageReportDecoder($this->cwd);
        return $decoder->decode((string) $result->stdout());
    }

    private function command(string $command, Traversable<string> $args = []) : string
    {
        $builder = Set {};
        $builder->add('%s %s %s');
        $builder->addAll([ static::PROGRAM, $command, implode(' ', $args) ]);

        return call_user_func_array('sprintf', $builder->toValuesArray());
    }

}


text:
const request = require("supertest"),
	path = require("path"),
	assert = require("chai").assert,
	appData = require(path.resolve("package.json")),
	app = require(path.resolve("src/index"));

describe("API", function() {

	describe("Health Check Resource", function() {

		it("should get app info", function(done) {

			request(app)
				.get("/healthCheck")
				.expect(200)
				.end(function(err, res) {
					if(!err) {
						const _result = res.body;

						assert.isObject(_result);
						assert.ok(_result.name === appData.name);
						assert.ok(_result.version === appData.version);
						assert.ok(_result.description === appData.description);
						assert.property(_result, "uptime");

						done();
					}
				});

		});

	});

});


text:
/// <reference path="../../typings/typescriptapp.d.ts" />

module VirtualFor {

    export class VirtualFor {

        constructor(private getHtml: IGetHtmlFn, private renderer: IRenderer ) { }

        public static createInstance = (getHtml: IGetHtmlFn, renderer: IRenderer) => {
            return new VirtualFor(getHtml, renderer);
        }

        public restirct: string = "A";
        public transclude: string = 'element';
        public scope: any = false;

        public compile = (template: ng.IAugmentedJQuery) => {
            var renderer: IRenderer = this.renderer;
            var parentElement = template.parent();
            var getHtml: IGetHtmlFn = this.getHtml;

            return  (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes, controller: any, transclude: any) => {
                transclude(scope.$new(), (clone: ng.IAugmentedJQuery) => {
                    removeCustomAttributes(clone, "virtual-for");

                    renderer.createInstance({
                        element: angular.element(parentElement),
                        template: getHtml(clone[0], true),
                        scope: scope,
                        attributes: attributes,
                        items: parseItems(scope,attributes),
                        dataService: attributes["virtualForDataService"],
                        searchTermNameOnScope: attributes["virtualForSearchTermNameOnScope"],
                        filterFnNameOnVm: attributes["virtualForFilterFnNameOnVm"]
                    }).render({ lastScrollY: 0, scrollY: 0 });

                });
            }

            function parseItems(scope: ng.IScope, attributes: ng.IAttributes): Array<any> {
                var match = attributes["virtualFor"].match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/);
                if (match) {
                    var collectionStringArray = match[2].split(".");
                    var items:any = scope;
                    for (var i = 0; i < collectionStringArray.length; i++) {
                        items = items[collectionStringArray[i]];
                    }
                    return items;
                } else {
                    return JSON.parse(attributes["virtualFor"]);
                }
            }

            function removeCustomAttributes(clone: ng.IAugmentedJQuery, prefix:string) {
                var names: Array<string> = [];
                var attributes = clone[0].attributes;
                for (var i = 0; i < attributes.length; i++) {
                    if (attributes[i].nodeName.indexOf(prefix) > -1)
                        names.push(attributes[i].nodeName);
                }

                names.forEach((name: string) => { clone[0].removeAttribute(name); });

            }

            function verifyRepeatExpression (repeatExpression) {
                if (repeatExpression.match(/limitTo/) || repeatExpression.match(/startFrom/)) {
                    throw new Error('"limitTo" and "startFrom" filters are not allowed in directive');
                }
            };
        }

    }

    angular.module("virtualFor").directive("virtualFor", ["virtualFor.getHtml","virtualFor.renderer",VirtualFor.createInstance]);
}


text:
package seedu.doit.logic;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static seedu.doit.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.doit.commons.core.Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX;
import static seedu.doit.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
import static seedu.doit.logic.commands.CommandResult.tasksToString;
import static seedu.doit.logic.commands.DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS;
import static seedu.doit.model.item.EndTime.MESSAGE_ENDTIME_CONSTRAINTS;
import static seedu.doit.model.item.Priority.MESSAGE_PRIORITY_CONSTRAINTS;
import static seedu.doit.model.item.StartTime.MESSAGE_STARTTIME_CONSTRAINTS;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import com.google.common.eventbus.Subscribe;

import seedu.doit.commons.core.EventsCenter;
import seedu.doit.commons.events.model.TaskManagerChangedEvent;
import seedu.doit.commons.events.ui.JumpToListRequestEvent;
import seedu.doit.commons.events.ui.ShowHelpRequestEvent;
import seedu.doit.commons.util.FileUtil;
import seedu.doit.logic.commands.AddCommand;
import seedu.doit.logic.commands.ClearCommand;
import seedu.doit.logic.commands.Command;
import seedu.doit.logic.commands.CommandResult;
import seedu.doit.logic.commands.DeleteCommand;
import seedu.doit.logic.commands.ExitCommand;
import seedu.doit.logic.commands.FindCommand;
import seedu.doit.logic.commands.HelpCommand;
import seedu.doit.logic.commands.ListCommand;
import seedu.doit.logic.commands.SaveCommand;
import seedu.doit.logic.commands.SelectCommand;
import seedu.doit.logic.commands.exceptions.CommandException;
import seedu.doit.model.Model;
import seedu.doit.model.ModelManager;
import seedu.doit.model.ReadOnlyTaskManager;
import seedu.doit.model.TaskManager;
import seedu.doit.model.comparators.TaskNameComparator;
import seedu.doit.model.item.Description;
import seedu.doit.model.item.EndTime;
import seedu.doit.model.item.Name;
import seedu.doit.model.item.Priority;
import seedu.doit.model.item.ReadOnlyTask;
import seedu.doit.model.item.Task;
import seedu.doit.model.tag.Tag;
import seedu.doit.model.tag.UniqueTagList;
import seedu.doit.storage.Storage;
import seedu.doit.storage.StorageManager;

public class LogicManagerTest {

    public static final String ADD_INVALID_TASK_NAME = "add []\\[;] p/12 e/15-3-2020 d/valid t/description";
    public static final String UNKNOWN_COMMAND = "uicfhmowqewca";
    public static final String TEMP_PREFERENCES_JSON = "TempPreferences.json";
    public static final String TEMP_TASK_MANAGER_XML = "TempTaskManager.xml";

    private static final String SAVE = SaveCommand.COMMAND_WORD + " ";

    /**
     * See https://github.com/junit-team/junit4/wiki/rules#temporaryfolder-rule
     */
    @Rule
    public TemporaryFolder saveFolder = new TemporaryFolder();

    private Model model;
    private Storage storage;
    private Logic logic;

    // These are for checking the correctness of the events raised
    private ReadOnlyTaskManager latestSavedTaskManager;
    private boolean helpShown;
    private int targetedJumpIndex;

    @Subscribe
    private void handleLocalModelChangedEvent(TaskManagerChangedEvent abce) {
        this.latestSavedTaskManager = new TaskManager(abce.data);
    }

    @Subscribe
    private void handleShowHelpRequestEvent(ShowHelpRequestEvent she) {
        this.helpShown = true;
    }

    @Subscribe
    private void handleJumpToListRequestEvent(JumpToListRequestEvent je) {
        this.targetedJumpIndex = je.targetIndex;
    }

    @Before
    public void setUp() {
        this.model = new ModelManager();
        String tempTaskManagerFile = this.saveFolder.getRoot().getPath() + TEMP_TASK_MANAGER_XML;
        String tempPreferencesFile = this.saveFolder.getRoot().getPath() + TEMP_PREFERENCES_JSON;
        this.storage = new StorageManager(tempTaskManagerFile, tempPreferencesFile);
        this.logic = new LogicManager(this.model, this.storage);
        EventsCenter.getInstance().registerHandler(this);

        this.latestSavedTaskManager = new TaskManager(this.model.getTaskManager());
        // last saved assumed to be up to date
        this.helpShown = false;
        this.targetedJumpIndex = -1; // non yet
    }

    @After
    public void tearDown() {
        EventsCenter.clearSubscribers();
    }

    @Test
    public void execute_invalid() {
        String invalidCommand = "       ";
        assertCommandFailure(invalidCommand, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE));
    }

    /**
     * Executes the command, confirms that a CommandException is not thrown and
     * that the result message is correct. Also confirms that both the 'task
     * manager' and the 'last shown list' are as specified.
     *
     * @see #assertCommandBehavior(boolean, String, String, ReadOnlyTaskManager,
     *      List)
     */
    private void assertCommandSuccess(String inputCommand, String expectedMessage,
            ReadOnlyTaskManager expectedTaskManager, List<? extends ReadOnlyTask> expectedShownList) {
        assertCommandBehavior(false, inputCommand, expectedMessage, expectedTaskManager, expectedShownList);
    }

    /**
     * Executes the command, confirms that a CommandException is thrown and that
     * the result message is correct. Both the 'task manager' and the 'last
     * shown list' are verified to be unchanged.
     *
     * @see #assertCommandBehavior(boolean, String, String, ReadOnlyTaskManager,
     *      List)
     */
    private void assertCommandFailure(String inputCommand, String expectedMessage) {
        TaskManager expectedTaskManager = new TaskManager(this.model.getTaskManager());
        List<ReadOnlyTask> expectedShownList = new ArrayList<>(this.model.getFilteredTaskList());
        assertCommandBehavior(true, inputCommand, expectedMessage, expectedTaskManager, expectedShownList);
    }

    /**
     * Executes the command, confirms that the result message is correct and
     * that a CommandException is thrown if expected and also confirms that the
     * following three parts of the LogicManager object's state are as
     * expected:

     * - the internal task manager data are same as those in the
     * {@code expectedTaskManager}

     * - the backing list shown by UI matches the {@code shownList}

     * - {@code expectedTaskManager} was saved to the storage file.

     */
    private void assertCommandBehavior(boolean isCommandExceptionExpected, String inputCommand, String expectedMessage,
            ReadOnlyTaskManager expectedTaskManager, List<? extends ReadOnlyTask> expectedShownList) {

        try {
            CommandResult result = this.logic.execute(inputCommand);
            assertFalse("CommandException expected but was not thrown.", isCommandExceptionExpected);
            assertEquals(expectedMessage, result.feedbackToUser);
        } catch (CommandException e) {
            assertTrue("CommandException not expected but was thrown.", isCommandExceptionExpected);
            assertEquals(expectedMessage, e.getMessage());
        }

        // Confirm the ui display elements should contain the right data
        assertEquals(expectedShownList, this.model.getFilteredTaskList());

        // Confirm the state of data (saved and in-memory) is as expected
        assertEquals(expectedTaskManager, this.model.getTaskManager());
        assertEquals(expectedTaskManager, this.latestSavedTaskManager);
    }

    @Test
    public void execute_unknownCommandWord() {
        String unknownCommand = UNKNOWN_COMMAND;
        assertCommandFailure(unknownCommand, MESSAGE_UNKNOWN_COMMAND);
    }

    @Test
    public void execute_help() {
        assertCommandSuccess(HelpCommand.COMMAND_WORD, HelpCommand.SHOWING_HELP_MESSAGE, new TaskManager(),
                Collections.emptyList());
        assertTrue(this.helpShown);
    }

    @Test
    public void execute_exit() {
        assertCommandSuccess(ExitCommand.COMMAND_WORD, ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT, new TaskManager(),
                Collections.emptyList());
    }

    @Test
    public void execute_clear() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        this.model.addTask(helper.generateTask(1));
        this.model.addTask(helper.generateTask(2));
        this.model.addTask(helper.generateTask(3));

        assertCommandSuccess(ClearCommand.COMMAND_WORD, ClearCommand.MESSAGE_SUCCESS,
                new TaskManager(), Collections.emptyList());
    }

    // @@author A0146809W
    @Test
    public void execute_add_invalidArgsFormat() {
        String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE);
        assertCommandFailure("add d/valid", expectedMessage);
        assertCommandFailure("add e/valid", expectedMessage);
        assertCommandFailure("add Valid Task p/1", MESSAGE_PRIORITY_CONSTRAINTS);
        assertCommandFailure("add Valid Task e/invalid time", MESSAGE_ENDTIME_CONSTRAINTS);
        assertCommandFailure("add Valid Task s/invalid e/tomorrow ", MESSAGE_STARTTIME_CONSTRAINTS);
        assertCommandFailure("add Valid Name e/gogo ", MESSAGE_ENDTIME_CONSTRAINTS);
    }
    // @@author

    @Test
    public void execute_add_invalidTaskData() {
        assertCommandFailure(ADD_INVALID_TASK_NAME, Name.MESSAGE_NAME_CONSTRAINTS);
    }

    @Test
    public void execute_add_successful() throws Exception {
        // setup expectations
        TestDataHelper helper = new TestDataHelper();
        Task toBeAdded = helper.adam();
        TaskManager expectedTM = new TaskManager();
        expectedTM.addTask(toBeAdded);

        // execute command and verify result
        assertCommandSuccess(helper.generateAddCommand(toBeAdded), String.format(AddCommand.MESSAGE_SUCCESS, toBeAdded),
                expectedTM, expectedTM.getTaskList());

    }

    @Test
    public void execute_addDuplicate_notAllowed() throws Exception {
        // setup expectations
        TestDataHelper helper = new TestDataHelper();
        Task toBeAdded = helper.adam();

        // setup starting state
        this.model.addTask(toBeAdded); // task already in internal task manager

        // execute command and verify result
        assertCommandFailure(helper.generateAddCommand(toBeAdded), AddCommand.MESSAGE_DUPLICATE_TASK);

    }

    @Test
    public void execute_list_showsAllTasks() throws Exception {
        // prepare expectations
        TestDataHelper helper = new TestDataHelper();
        TaskManager expectedTM = helper.generateTaskManager(2);
        List<? extends ReadOnlyTask> expectedList = expectedTM.getTaskList();

        // prepare task manager state
        helper.addToModel(this.model, 2);

        assertCommandSuccess(ListCommand.COMMAND_WORD, ListCommand.MESSAGE_SUCCESS, expectedTM, expectedList);
    }

    /**
     * Confirms the 'invalid argument index number behaviour' for the given
     * command targeting a single task in the shown list, using visible index.
     *
     * @param commandWord
     *            to test assuming it targets a single task in the last shown
     *            list based on visible index.
     */
    private void assertIncorrectIndexFormatBehaviorForCommand(String commandWord, String expectedMessage)
            throws Exception {
        assertCommandFailure(commandWord, expectedMessage); // index missing
        assertCommandFailure(commandWord + " +1", expectedMessage); // index
                                                                    // should be
                                                                    // unsigned
        assertCommandFailure(commandWord + " -1", expectedMessage); // index
                                                                    // should be
                                                                    // unsigned
        assertCommandFailure(commandWord + " 0", expectedMessage); // index
                                                                   // cannot be
                                                                   // 0
        assertCommandFailure(commandWord + " not_a_number", expectedMessage);
    }

    /**
     * Confirms the 'invalid argument index number behaviour' for the given
     * command targeting a single task in the shown list, using visible index.
     *
     * @param commandWord
     *            to test assuming it targets a single task in the last shown
     *            list based on visible index.
     */
    private void assertIndexNotFoundBehaviorForCommand(String commandWord) throws Exception {
        String expectedMessage = MESSAGE_INVALID_TASK_DISPLAYED_INDEX;
        TestDataHelper helper = new TestDataHelper();
        List<Task> taskList = helper.generateTaskList(2);

        // set AB state to 2 tasks
        this.model.resetData(new TaskManager());
        for (Task p : taskList) {
            this.model.addTask(p);
        }

        assertCommandFailure(commandWord + " 3", expectedMessage);
    }

    @Test
    public void execute_selectInvalidArgsFormat_errorMessageShown() throws Exception {
        String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, SelectCommand.MESSAGE_USAGE);
        assertIncorrectIndexFormatBehaviorForCommand("select", expectedMessage);
    }

    @Test
    public void execute_selectIndexNotFound_errorMessageShown() throws Exception {
        assertIndexNotFoundBehaviorForCommand("select");
    }

    @Test
    public void execute_select_jumpsToCorrectTask() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        List<Task> threeTasks = helper.generateTaskList(3);

        TaskManager expectedTM = helper.generateTaskManager(threeTasks);
        helper.addToModel(this.model, threeTasks);

        assertEquals(this.model.getFilteredTaskList().get(1), threeTasks.get(1));
    }

    @Test
    public void execute_deleteInvalidArgsFormat_errorMessageShown() throws Exception {
        String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE);
        assertIncorrectIndexFormatBehaviorForCommand("delete", expectedMessage);
    }

    @Test
    public void execute_deleteIndexNotFound_errorMessageShown() throws Exception {
        assertIndexNotFoundBehaviorForCommand("delete");
    }

    // @@author A0146809W
    @Test
    public void execute_delete_removesCorrectTask() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        List<Task> threeTasks = helper.generateTaskList(3);

        TaskManager expectedTM = helper.generateTaskManager(threeTasks);
        expectedTM.removeTask(threeTasks.get(1));
        helper.addToModel(this.model, threeTasks);

        HashSet<ReadOnlyTask> tasksToDelete = new HashSet<>();
        tasksToDelete.add(threeTasks.get(1));

        String resultMessage = String.format(MESSAGE_DELETE_TASK_SUCCESS, tasksToString(tasksToDelete));

        assertCommandSuccess("delete 2", resultMessage, expectedTM, expectedTM.getTaskList());
    }

    @Test
    public void execute_delete_removesValidRangeOfTasks() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        List<Task> fourTasks = helper.generateTaskList(4);

        TaskManager expectedTM = helper.generateTaskManager(fourTasks);
        expectedTM.removeTask(fourTasks.get(0));
        expectedTM.removeTask(fourTasks.get(1));
        expectedTM.removeTask(fourTasks.get(2));
        expectedTM.removeTask(fourTasks.get(3));

        helper.addToModel(this.model, fourTasks);

        HashSet<ReadOnlyTask> deletedTasks = helper.generateTaskSet(fourTasks.get(0), fourTasks.get(1),
            fourTasks.get(2), fourTasks.get(3));
        String tasksAsString = CommandResult.tasksToString(deletedTasks);

        // Delete all tasks ranging from 1 to 4
        // Then checks if the task manager have no tasks left
        assertCommandBehavior(false, "delete 1-4",
                String.format(DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS, tasksAsString), expectedTM,
                expectedTM.getTaskList());
    }

    @Test
    public void execute_delete_removesMultipleTasksNotInOrder() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        List<Task> fourTasks = helper.generateTaskList(5);

        TaskManager expectedTM = helper.generateTaskManager(fourTasks);
        expectedTM.removeTask(fourTasks.get(0));
        expectedTM.removeTask(fourTasks.get(3));

        helper.addToModel(this.model, fourTasks);

        HashSet<ReadOnlyTask> deletedTasks = helper.generateTaskSet(fourTasks.get(0), fourTasks.get(3));
        String tasksAsString = CommandResult.tasksToString(deletedTasks);

        // Delete tasks 1 and 4
        // Then checks if the task manager have no tasks left
        assertCommandBehavior(false, "delete 1 4",
                String.format(DeleteCommand.MESSAGE_DELETE_TASK_SUCCESS, tasksAsString), expectedTM,
                expectedTM.getTaskList());
    }
    // @@author

    @Test
    public void execute_find_invalidArgsFormat() {
        String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE);
        assertCommandFailure("find ", expectedMessage);
    }

    @Test
    public void execute_find_onlyMatchesFullWordsInNames() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        Task pTarget1 = helper.generateTaskWithName("bla bla KEY bla");
        Task pTarget2 = helper.generateTaskWithName("bla KEY bla bceofeia");
        Task p1 = helper.generateTaskWithName("KE Y");
        Task p2 = helper.generateTaskWithName("KEYKEYKEY sduauo");

        List<Task> fourTasks = helper.generateTaskList(p1, pTarget1, p2, pTarget2);
        Collections.sort(fourTasks, new TaskNameComparator());
        TaskManager expectedTM = helper.generateTaskManager(fourTasks);
        List<Task> expectedList = helper.generateTaskList(pTarget1, pTarget2);
        Collections.sort(expectedList, new TaskNameComparator());
        helper.addToModel(this.model, fourTasks);

        assertCommandSuccess("find n/KEY", Command.getMessageForTaskListShownSummary(expectedList.size()), expectedTM,
                expectedList);
    }

    @Test
    public void execute_find_isNotCaseSensitive() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        Task p1 = helper.generateTaskWithName("bla bla KEY bla");
        Task p2 = helper.generateTaskWithName("bla KEY bla bceofeia");
        Task p3 = helper.generateTaskWithName("key key");
        Task p4 = helper.generateTaskWithName("KEy sduauo");

        List<Task> fourTasks = helper.generateTaskList(p3, p1, p4, p2);
        Collections.sort(fourTasks, new TaskNameComparator());
        TaskManager expectedTM = helper.generateTaskManager(fourTasks);
        List<Task> expectedList = fourTasks;
        helper.addToModel(this.model, fourTasks);

        assertCommandSuccess("find n/KEY", Command.getMessageForTaskListShownSummary(expectedList.size()), expectedTM,
                expectedList);
    }

    @Test
    public void execute_find_matchesIfAnyKeywordPresent() throws Exception {
        TestDataHelper helper = new TestDataHelper();
        Task pTarget1 = helper.generateTaskWithName("bla bla KEY bla");
        Task pTarget2 = helper.generateTaskWithName("key rAnDoM bla bceofeia");
        Task pTarget3 = helper.generateTaskWithName("key key");
        Task p1 = helper.generateTaskWithName("sduauo");

        List<Task> fourTasks = helper.generateTaskList(pTarget1, p1, pTarget2, pTarget3);
        TaskManager expectedTM = helper.generateTaskManager(fourTasks);
        List<Task> expectedList = helper.generateTaskList(pTarget2);
        helper.addToModel(this.model, fourTasks);

        assertCommandSuccess("find n/key rAnDoM", Command.getMessageForTaskListShownSummary(expectedList.size()),
                expectedTM, expectedList);
    }
    // @@author

    // @@author A0138909R
    @Test
    public void execute_save_successful() throws Exception {
        String filePath = "data/testfile1.xml";
        File file = new File(filePath);
        file.delete();
        assertCommandSuccess(SAVE + filePath, String.format(SaveCommand.MESSAGE_SUCCESS, filePath),
                this.model.getTaskManager(), this.model.getFilteredTaskList());
        file.delete();
    }

    @Test
    public void execute_save_not_xml() throws Exception {
        String filePath = "";
        assertCommandFailure(SAVE + filePath, SaveCommand.MESSAGE_NOT_XML_FILE);
    }

    @Test
    public void execute_save_invalidFileName() throws Exception {
        String filePath = "data/??.xml";
        assertCommandFailure(SAVE + filePath, SaveCommand.MESSAGE_INVALID_FILE_NAME);
    }

    @Test
    public void execute_save_duplicateFile() throws Exception {
        String filePath = "data/testfile3.xml";
        File file = new File(filePath);
        FileUtil.createIfMissing(file);
        assertCommandFailure(SAVE + filePath, SaveCommand.MESSAGE_DUPLICATE_FILE);
        file.delete();
    }

    @Test
    public void execute_save_inSameFile() throws Exception {
        String filePath = this.storage.getTaskManagerFilePath();
        assertCommandFailure(SAVE + filePath, filePath + SaveCommand.MESSAGE_USING_SAME_FILE);
    }

    // @@author
    /**
     * A utility class to generate test data.
     */
    class TestDataHelper {

        private static final String PRIORITY_LOW = "low";

        Task adam() throws Exception {
            Name name = new Name("Adam Brown");
            Priority privatePriority = new Priority(PRIORITY_LOW);
            EndTime endTime = new EndTime("tomorrow");
            Description description = new Description("111, alpha street");
            Tag tag1 = new Tag("tag1");
            Tag tag2 = new Tag("longertag2");
            UniqueTagList tags = new UniqueTagList(tag1, tag2);
            return new Task(name, privatePriority, endTime, description, tags);
        }

        /**
         * Generates a valid task using the given seed. Running this function
         * with the same parameter values guarantees the returned task will have
         * the same state. Each unique seed will generate a unique Task object.
         *
         * @param seed
         *            used to generate the task data field values
         */
        private Task generateTask(int seed) throws Exception {
            return new Task(new Name("Task " + seed), new Priority("high"), new EndTime("today " + "2359"),
                    new Description("House of " + seed),
                    new UniqueTagList(new Tag("tag" + Math.abs(seed)), new Tag("tag" + Math.abs(seed + 1))));
        }

        /**
         * Generates the correct add command based on the task given
         */
        private String generateAddCommand(Task p) {
            StringBuffer cmd = new StringBuffer();

            cmd.append("add ");

            cmd.append(p.getName().toString());
            cmd.append(" e/").append(p.getDeadline());
            cmd.append(" p/").append(p.getPriority());
            cmd.append(" d/").append(p.getDescription());

            UniqueTagList tags = p.getTags();
            for (Tag t : tags) {
                cmd.append(" t/").append(t.tagName);
            }

            return cmd.toString();
        }

        /**
         * Generates an TaskManager with auto-generated tasks.
         */
        private TaskManager generateTaskManager(int numGenerated) throws Exception {
            TaskManager taskManager = new TaskManager();
            addToTaskManager(taskManager, numGenerated);
            return taskManager;
        }

        /**
         * Generates an TaskManager based on the list of Tasks given.
         */
        private TaskManager generateTaskManager(List<Task> tasks) throws Exception {
            TaskManager taskManager = new TaskManager();
            addToTaskManager(taskManager, tasks);
            return taskManager;
        }

        /**
         * Adds auto-generated Task objects to the given TaskManager
         *
         * @param taskManager
         *            The TaskManager to which the Tasks will be added
         */
        private void addToTaskManager(TaskManager taskManager, int numGenerated) throws Exception {
            addToTaskManager(taskManager, generateTaskList(numGenerated));
        }

        /**
         * Adds the given list of Tasks to the given TaskManager
         */
        private void addToTaskManager(TaskManager taskManager, List<Task> tasksToAdd) throws Exception {
            for (Task p : tasksToAdd) {
                taskManager.addTask(p);
            }
        }

        /**
         * Adds auto-generated Task objects to the given model
         *
         * @param model
         *            The model to which the Tasks will be added
         */
        private void addToModel(Model model, int numGenerated) throws Exception {
            addToModel(model, generateTaskList(numGenerated));
        }

        /**
         * Adds the given list of Tasks to the given model
         */
        private void addToModel(Model model, List<Task> tasksToAdd) throws Exception {
            for (Task p : tasksToAdd) {
                model.addTask(p);
            }
        }

        /**
         * Generates a list of Tasks based on the flags.
         */
        private List<Task> generateTaskList(int numGenerated) throws Exception {
            List<Task> tasks = new ArrayList<>();
            for (int i = 1; i <= numGenerated; i++) {
                tasks.add(generateTask(i));
            }
            return tasks;
        }

        private List<Task> generateTaskList(Task... tasks) {
            return Arrays.asList(tasks);
        }

        /**
         * Generates a Task object with given name. Other fields will have some
         * dummy values.
         */
        private Task generateTaskWithName(String name) throws Exception {
            return new Task(new Name(name), new Priority(PRIORITY_LOW), new EndTime("today"),
                    new Description("House of 1"), new UniqueTagList(new Tag("tag")));
        }

        private HashSet<ReadOnlyTask> generateTaskSet(ReadOnlyTask... tasks) {
            return new HashSet<>(Arrays.asList(tasks));
        }
    }
}


text:
require 'em-synchrony'
require 'em-synchrony/mysql2'
require 'em-synchrony/fiber_iterator'
require 'yaml'

options = YAML.load_file(File.expand_path('../../../spec/database.yml', __FILE__))
puts options.inspect

number_of = 10
concurrency = 2
connection_pool_size = 4
results = []

db = EM::Synchrony::ConnectionPool.new(size: connection_pool_size) do
  Mysql2::EM::Client.new(options)
end

EM.synchrony do
  EM::Synchrony::FiberIterator.new(0...number_of, concurrency).each do |i|
    puts i
    aquery = db.aquery('select sleep(1)')
    aquery.callback do |r|
      puts 'callback'
      results << r.first
      EM.stop if results.size >= number_of
    end
  end

  puts "results.size #{results.size}"
end

puts results.inspect
puts "results.size #{results.size}"

# time ruby test/async/mysql2_aquery.rb
# 并发数 >= db连接池的场合,aquery要等空闲连接出来,耗时和query一样
# 并发数 < db连接池的场合,aquery可以马上用空闲连接发起下一波查询,也就更早拿到callback,比query快


text:
using System.Collections.Generic;
using System.Linq;
using ESRI.ArcLogistics.App.Pages;
using ESRI.ArcLogistics.DomainObjects;

namespace ESRI.ArcLogistics.App.Commands
{
    /// <summary>
    /// Command deletes fuel types
    /// </summary>
    class DeleteFuelTypes : DeleteCommandBase<FuelType>
    {
        #region Public Fields

        public const string COMMAND_NAME = "ArcLogistics.Commands.DeleteFuelTypes";

        public override string Name
        {
            get
            {
                return COMMAND_NAME;
            }
        }

        #endregion

        #region DeleteCommandBase Protected Methods

        /// <summary>
        /// Deletes fuel types
        /// </summary>
        protected override void _Delete(IList<FuelType> selectedObjects)
        {
            var deletionChecker = _Application.Project.DeletionCheckingService;

            var fuelType = deletionChecker.QueryAssignedFuelTypes(selectedObjects)
                .FirstOrDefault();
            if (fuelType != null)
            {
                var message = _Application.GetString(ASSIGNED_TO_VEHICLE_KEY, fuelType);
                _Application.Messenger.AddError(message);

                return;
            }

            foreach (FuelType ft in selectedObjects)
                App.Current.Project.FuelTypes.Remove(ft);

            App.Current.Project.Save();
        }

        #endregion DeleteCommandBase Protected Methods

        #region DeleteCommandBase Protected Properties

        protected override ISupportDataObjectEditing ParentPage
        {
            get
            {
                if (_parentPage == null)
                {
                    FuelPage page = (FuelPage)((MainWindow)App.Current.MainWindow).GetPage(PagePaths.FuelTypesPagePath);
                    _parentPage = page;
                }

                return _parentPage;
            }
        }

        #endregion DeleteCommandBase Protected Properties

        #region Private Members

        private ISupportDataObjectEditing _parentPage;

        #endregion Private Members

        #region private constants
        /// <summary>
        /// Resource key for accessing message reporting about object assigned to one or more
        /// vehicle.
        /// </summary>
        private const string ASSIGNED_TO_VEHICLE_KEY = "FuelTypeAssignedToVehicle";
        #endregion
    }
}


text:
//  BankVirtuals.cs  (c) 2003 Kari Laitinen

using System ;

class  BankAccount
{
   protected  string  account_owner ;
   protected  long    account_number ;
   protected  double  account_balance ;

   public BankAccount( string  given_account_owner,
                       long    given_account_number,
                       double  initial_balance )
   {
      account_owner    =  given_account_owner ;
      account_number   =  given_account_number ;
      account_balance  =  initial_balance  ;
   }

   public void show_account_data()
   {
      Console.Write( "\n\nB A N K   A C C O U N T   D A T A : "
                  +  "\n   Account owner :  "  +  account_owner
                  +  "\n   Account number:  "  +  account_number
                  +  "\n   Current balance: "  +  account_balance ) ;
   }

   public virtual void deposit_money( double amount_to_deposit )
   {
      Console.Write( "\n\nTRANSACTION FOR ACCOUNT OF " +  account_owner
                  +  " (Account number " +  account_number  + ")" ) ;
      Console.Write( "\n   Amount deposited: "  +  amount_to_deposit
                  +  "\n   Old account balance: "  +  account_balance ) ;
      account_balance  =  account_balance  +  amount_to_deposit ;
      Console.Write( "   New balance: "  +  account_balance  ) ;
   }

   public virtual void withdraw_money( double amount_to_withdraw )
   {
      Console.Write( "\n\nTRANSACTION FOR ACCOUNT OF " +  account_owner
                  +  " (Account number " +  account_number  + ")" ) ;

      if ( account_balance  <  amount_to_withdraw )
      {
         Console.Write("\n   -- Transaction not completed: "
                + "Not enough money to withdraw " + amount_to_withdraw ) ;
      }
      else
      {
         Console.Write("\n   Amount withdrawn:    "  +  amount_to_withdraw
                     + "\n   Old account balance: "  +  account_balance ) ;
         account_balance  =  account_balance  -  amount_to_withdraw ;
         Console.Write("   New balance: "  +  account_balance ) ;
      }
   }

   public void transfer_money_to( BankAccount  receiving_account,
                                  double       amount_to_transfer )
   {
      Console.Write( "\n\nTRANSACTION FOR ACCOUNT OF " +  account_owner
                  +  " (Account number " +  account_number  + ")" ) ;

      if ( account_balance  >=  amount_to_transfer )
      {
         receiving_account.account_balance  =
            receiving_account.account_balance  +  amount_to_transfer ;

         Console.Write("\n   " + amount_to_transfer + " was transferred to "
              + receiving_account.account_owner  +  " (Account no. "
              + receiving_account.account_number +  ")."
              + "\n   Balance before transfer: " +  account_balance ) ;
         account_balance  =  account_balance  -  amount_to_transfer ;
         Console.Write("   New balance:  " +  account_balance ) ;
      }
      else
      {
         Console.Write( "\n   -- Not enough money for transfer." ) ;
      }
   }
}

class  AccountWithCredit  :  BankAccount
{
   protected  double  credit_limit ;

   public  AccountWithCredit( string  given_account_owner,
                              long    given_account_number,
                              double  initial_balance,
                              double  given_credit_limit  )

       : base( given_account_owner,
               given_account_number,
               initial_balance )
   {
      credit_limit  =  given_credit_limit ;
   }

   public override void withdraw_money( double amount_to_withdraw )
   {
      Console.Write( "\n\nTRANSACTION FOR ACCOUNT OF " +  account_owner
                  +  " (Account number " +  account_number  + ")" ) ;

      if ( account_balance  +  credit_limit  <  amount_to_withdraw )
      {
         Console.Write(
               "\n   --  Transaction not completed: "
             + "Not enough credit to withdraw "+ amount_to_withdraw ) ;
      }
      else
      {
         Console.Write(
                "\n   Amount withdrawn:    "  +  amount_to_withdraw
              + "\n   Old account balance: "  +  account_balance ) ;
         account_balance  =  account_balance  -  amount_to_withdraw ;
         Console.Write( "   New balance: "  +  account_balance ) ;
      }
   }
}

class  RestrictedAccount  :  BankAccount
{
   protected double  maximum_amount_to_withdraw ;

   public RestrictedAccount( string  given_account_owner,
                             long    given_account_number,
                             double  initial_balance,
                             double  given_withdrawal_limit  )

       : base( given_account_owner,
               given_account_number,
               initial_balance )
   {
      maximum_amount_to_withdraw  =  given_withdrawal_limit ;
   }

   public override void withdraw_money( double amount_to_withdraw )
   {
      if ( amount_to_withdraw  >  maximum_amount_to_withdraw )
      {
         Console.Write(
                 "\n\nTRANSACTION FOR ACCOUNT OF " +  account_owner
              +  " (Account number " +  account_number  + ")" ) ;

         Console.Write(
                 "\n   -- Transaction not completed: Cannot withdraw "
              +  amount_to_withdraw   + "\n   -- Withdrawal limit is "
              +  maximum_amount_to_withdraw + "." ) ;
      }
      else
      {
         base.withdraw_money( amount_to_withdraw ) ;
      }
   }
}

class BankVirtuals
{
   static void Main()
   {
      BankAccount  beatles_account  =
                     new  BankAccount( "John Lennon", 222222, 2000.00 ) ;

      AccountWithCredit  stones_account  =
                       new  AccountWithCredit( "Brian Jones", 333333,
                                                2000.00,  1000.00 ) ;

      RestrictedAccount   doors_account  =
                       new  RestrictedAccount( "Jim Morrison", 444444,
                                               4000.00,  1000.00 ) ;

      beatles_account.withdraw_money( 2500.00 ) ;
      stones_account.withdraw_money( 2500.00 ) ;
      doors_account.withdraw_money( 2500.00 ) ;
   }
}


text:
/**
 * @module ol/renderer/canvas/Layer
 */
import {inherits} from '../../index.js';
import {getBottomLeft, getBottomRight, getTopLeft, getTopRight} from '../../extent.js';
import {TRUE} from '../../functions.js';
import RenderEvent from '../../render/Event.js';
import RenderEventType from '../../render/EventType.js';
import {rotateAtOffset} from '../../render/canvas.js';
import CanvasImmediateRenderer from '../../render/canvas/Immediate.js';
import LayerRenderer from '../Layer.js';
import {create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js';

/**
 * @constructor
 * @abstract
 * @extends {module:ol/renderer/Layer}
 * @param {module:ol/layer/Layer} layer Layer.
 */
const CanvasLayerRenderer = function(layer) {

  LayerRenderer.call(this, layer);

  /**
   * @protected
   * @type {number}
   */
  this.renderedResolution;

  /**
   * @private
   * @type {module:ol/transform~Transform}
   */
  this.transform_ = createTransform();

};

inherits(CanvasLayerRenderer, LayerRenderer);

/**
 * @param {CanvasRenderingContext2D} context Context.
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/extent~Extent} extent Clip extent.
 * @protected
 */
CanvasLayerRenderer.prototype.clip = function(context, frameState, extent) {
  const pixelRatio = frameState.pixelRatio;
  const width = frameState.size[0] * pixelRatio;
  const height = frameState.size[1] * pixelRatio;
  const rotation = frameState.viewState.rotation;
  const topLeft = getTopLeft(/** @type {module:ol/extent~Extent} */ (extent));
  const topRight = getTopRight(/** @type {module:ol/extent~Extent} */ (extent));
  const bottomRight = getBottomRight(/** @type {module:ol/extent~Extent} */ (extent));
  const bottomLeft = getBottomLeft(/** @type {module:ol/extent~Extent} */ (extent));

  applyTransform(frameState.coordinateToPixelTransform, topLeft);
  applyTransform(frameState.coordinateToPixelTransform, topRight);
  applyTransform(frameState.coordinateToPixelTransform, bottomRight);
  applyTransform(frameState.coordinateToPixelTransform, bottomLeft);

  context.save();
  rotateAtOffset(context, -rotation, width / 2, height / 2);
  context.beginPath();
  context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);
  context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);
  context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);
  context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);
  context.clip();
  rotateAtOffset(context, rotation, width / 2, height / 2);
};

/**
 * @param {module:ol/render/EventType} type Event type.
 * @param {CanvasRenderingContext2D} context Context.
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/transform~Transform=} opt_transform Transform.
 * @private
 */
CanvasLayerRenderer.prototype.dispatchComposeEvent_ = function(type, context, frameState, opt_transform) {
  const layer = this.getLayer();
  if (layer.hasListener(type)) {
    const width = frameState.size[0] * frameState.pixelRatio;
    const height = frameState.size[1] * frameState.pixelRatio;
    const rotation = frameState.viewState.rotation;
    rotateAtOffset(context, -rotation, width / 2, height / 2);
    const transform = opt_transform !== undefined ?
      opt_transform : this.getTransform(frameState, 0);
    const render = new CanvasImmediateRenderer(
      context, frameState.pixelRatio, frameState.extent, transform,
      frameState.viewState.rotation);
    const composeEvent = new RenderEvent(type, render, frameState,
      context, null);
    layer.dispatchEvent(composeEvent);
    rotateAtOffset(context, rotation, width / 2, height / 2);
  }
};

/**
 * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.
 * @param {module:ol/PluggableMap~FrameState} frameState FrameState.
 * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
 *     callback.
 * @param {S} thisArg Value to use as `this` when executing `callback`.
 * @return {T|undefined} Callback result.
 * @template S,T,U
 */
CanvasLayerRenderer.prototype.forEachLayerAtCoordinate = function(coordinate, frameState, callback, thisArg) {
  const hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, 0, TRUE, this);

  if (hasFeature) {
    return callback.call(thisArg, this.getLayer(), null);
  } else {
    return undefined;
  }
};

/**
 * @param {CanvasRenderingContext2D} context Context.
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/layer/Layer~State} layerState Layer state.
 * @param {module:ol/transform~Transform=} opt_transform Transform.
 * @protected
 */
CanvasLayerRenderer.prototype.postCompose = function(context, frameState, layerState, opt_transform) {
  this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, context, frameState, opt_transform);
};

/**
 * @param {CanvasRenderingContext2D} context Context.
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/transform~Transform=} opt_transform Transform.
 * @protected
 */
CanvasLayerRenderer.prototype.preCompose = function(context, frameState, opt_transform) {
  this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, context, frameState, opt_transform);
};

/**
 * @param {CanvasRenderingContext2D} context Context.
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/transform~Transform=} opt_transform Transform.
 * @protected
 */
CanvasLayerRenderer.prototype.dispatchRenderEvent = function(context, frameState, opt_transform) {
  this.dispatchComposeEvent_(RenderEventType.RENDER, context, frameState, opt_transform);
};

/**
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {number} offsetX Offset on the x-axis in view coordinates.
 * @protected
 * @return {!module:ol/transform~Transform} Transform.
 */
CanvasLayerRenderer.prototype.getTransform = function(frameState, offsetX) {
  const viewState = frameState.viewState;
  const pixelRatio = frameState.pixelRatio;
  const dx1 = pixelRatio * frameState.size[0] / 2;
  const dy1 = pixelRatio * frameState.size[1] / 2;
  const sx = pixelRatio / viewState.resolution;
  const sy = -sx;
  const angle = -viewState.rotation;
  const dx2 = -viewState.center[0] + offsetX;
  const dy2 = -viewState.center[1];
  return composeTransform(this.transform_, dx1, dy1, sx, sy, angle, dx2, dy2);
};

/**
 * @abstract
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/layer/Layer~State} layerState Layer state.
 * @param {CanvasRenderingContext2D} context Context.
 */
CanvasLayerRenderer.prototype.composeFrame = function(frameState, layerState, context) {};

/**
 * @abstract
 * @param {module:ol/PluggableMap~FrameState} frameState Frame state.
 * @param {module:ol/layer/Layer~State} layerState Layer state.
 * @return {boolean} whether composeFrame should be called.
 */
CanvasLayerRenderer.prototype.prepareFrame = function(frameState, layerState) {};
export default CanvasLayerRenderer;


text:
require 'spec_helper'

RSpec.describe Import::ImportedLoginController, type: :controller do

  # TODO: auto-generated
  describe '#confirm_user' do
    xit 'GET confirm_user' do
      get :confirm_user

      expect(response).to have_http_status(:ok)
    end
  end

end


text:
package org.kie.workbench.common.screens.library.client.screens.samples;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.inject.Inject;

import org.guvnor.common.services.project.client.context.WorkspaceProjectContext;
import org.guvnor.common.services.project.context.WorkspaceProjectContextChangeEvent;
import org.jboss.errai.bus.client.api.messaging.Message;
import org.jboss.errai.common.client.api.Caller;
import org.jboss.errai.common.client.dom.HTMLElement;
import org.jboss.errai.ioc.client.api.ManagedInstance;
import org.kie.workbench.common.screens.examples.model.ExampleOrganizationalUnit;
import org.kie.workbench.common.screens.examples.model.ExampleProject;
import org.kie.workbench.common.screens.examples.service.ExamplesService;
import org.kie.workbench.common.screens.library.api.LibraryService;
import org.kie.workbench.common.screens.library.client.perspective.LibraryPerspective;
import org.kie.workbench.common.screens.library.client.util.LibraryPlaces;
import org.kie.workbench.common.screens.library.client.widgets.common.TileWidget;
import org.uberfire.client.annotations.WorkbenchPartTitle;
import org.uberfire.client.annotations.WorkbenchPartView;
import org.uberfire.client.annotations.WorkbenchScreen;
import org.uberfire.client.mvp.UberElement;
import org.uberfire.ext.widgets.common.client.callbacks.DefaultErrorCallback;
import org.uberfire.ext.widgets.common.client.callbacks.HasBusyIndicatorDefaultErrorCallback;
import org.uberfire.ext.widgets.common.client.common.HasBusyIndicator;
import org.uberfire.lifecycle.OnStartup;
import org.uberfire.mvp.Command;
import org.uberfire.mvp.PlaceRequest;
import org.uberfire.workbench.events.NotificationEvent;

@WorkbenchScreen(identifier = LibraryPlaces.IMPORT_PROJECTS_SCREEN,
        owningPerspective = LibraryPerspective.class)
public class ImportWorkspaceProjectsScreen {

    public interface View extends UberElement<ImportWorkspaceProjectsScreen>,
                                  HasBusyIndicator {

        void setTitle(String title);

        void clearProjects();

        void addProject(HTMLElement project);

        String getNumberOfAssetsMessage(int numberOfAssets);

        String getTrySamplesLabel();

        String getNoProjectsToImportMessage();

        String getImportingMessage();

        String getLoadingMessage();

        String getNoProjectsSelectedMessage();

        String getImportProjectsSuccessMessage();
    }

    private View view;

    private LibraryPlaces libraryPlaces;

    private Caller<LibraryService> libraryService;

    private ManagedInstance<TileWidget> tileWidgets;

    private Caller<ExamplesService> examplesService;

    private WorkspaceProjectContext projectContext;
    private Event<NotificationEvent> notificationEvent;

    private Event<WorkspaceProjectContextChangeEvent> projectContextChangeEvent;

    private Map<ExampleProject, TileWidget> projectWidgetsByName;

    @Inject
    public ImportWorkspaceProjectsScreen(final View view,
                                         final LibraryPlaces libraryPlaces,
                                         final Caller<LibraryService> libraryService,
                                         final ManagedInstance<TileWidget> tileWidgets,
                                         final Caller<ExamplesService> examplesService,
                                         final WorkspaceProjectContext projectContext,
                                         final Event<NotificationEvent> notificationEvent,
                                         final Event<WorkspaceProjectContextChangeEvent> projectContextChangeEvent) {
        this.view = view;
        this.libraryPlaces = libraryPlaces;
        this.libraryService = libraryService;
        this.tileWidgets = tileWidgets;
        this.examplesService = examplesService;
        this.projectContext = projectContext;
        this.notificationEvent = notificationEvent;
        this.projectContextChangeEvent = projectContextChangeEvent;
    }

    @OnStartup
    public void onStartup(final PlaceRequest placeRequest) {
        view.init(this);

        final String title = placeRequest.getParameter("title",
                                                       view.getTrySamplesLabel());
        view.setTitle(title);

        final String trySamples = placeRequest.getParameter("trySamples",
                                                            "false");
        final String repositoryUrl = placeRequest.getParameter("repositoryUrl",
                                                               null);

        if (repositoryUrl != null || Boolean.valueOf(trySamples)) {
            view.showBusyIndicator(view.getLoadingMessage());
            libraryService.call((Set<ExampleProject> projects) -> {
                                    view.hideBusyIndicator();
                                    setupProjects(projects);
                                },
                                new DefaultErrorCallback() {
                                    @Override
                                    public boolean error(final Message message,
                                                         final Throwable throwable) {
                                        view.hideBusyIndicator();
                                        showNoProjects();
                                        return super.error(message,
                                                           throwable);
                                    }
                                }).getProjects(repositoryUrl);
        }
    }

    public void setupEvent(@Observes final ImportProjectsSetupEvent event) {
        setupProjects(event.getProjects());
    }

    private void setupProjects(final Set<ExampleProject> projects) {
        if (projects == null || projects.isEmpty()) {
            showNoProjects();
            return;
        }

        projectWidgetsByName = new HashMap<>();
        projects.forEach(project -> {
            TileWidget projectWidget = createProjectWidget(project);
            projectWidgetsByName.put(project,
                                     projectWidget);
        });

        updateView(projectWidgetsByName.values());
    }

    private TileWidget createProjectWidget(final ExampleProject project) {
        TileWidget tileWidget = tileWidgets.get();
        tileWidget.init(project.getName(),
                        project.getDescription(),
                        null,
                        null,
                        selectCommand(tileWidget));
        return tileWidget;
    }

    private void showNoProjects() {
        notificationEvent.fire(new NotificationEvent(view.getNoProjectsToImportMessage(),
                                                     NotificationEvent.NotificationType.ERROR));
        libraryPlaces.goToLibrary();
    }

    private void updateView(final Collection<TileWidget> projectWidgets) {
        view.clearProjects();
        final List<TileWidget> sortedProjectWidgets = sortProjectWidgets(projectWidgets);
        sortedProjectWidgets.stream().forEach(projectWidget -> {
            view.addProject(projectWidget.getView().getElement());
        });
    }

    private List<TileWidget> sortProjectWidgets(final Collection<TileWidget> projectWidgets) {
        final List<TileWidget> sortedProjectWidgets = new ArrayList<>(projectWidgets);
        Collections.sort(sortedProjectWidgets,
                         Comparator.comparing(o -> o.getLabel().toUpperCase()));
        return sortedProjectWidgets;
    }

    private Command selectCommand(final TileWidget tileWidget) {
        return () -> tileWidget.setSelected(!tileWidget.isSelected());
    }

    public List<TileWidget> filterProjects(final String filter) {
        List<TileWidget> filteredProjectWidgets = projectWidgetsByName.entrySet().stream()
                .filter(p -> p.getKey().getName().toUpperCase().contains(filter.toUpperCase()))
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());

        updateView(filteredProjectWidgets);

        return filteredProjectWidgets;
    }

    public void ok() {
        final List<ExampleProject> projects = projectWidgetsByName.entrySet().stream()
                .filter(p -> p.getValue().isSelected())
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        if (projects.isEmpty()) {
            notificationEvent.fire(new NotificationEvent(view.getNoProjectsSelectedMessage(),
                                                         NotificationEvent.NotificationType.ERROR));
            return;
        }

        view.showBusyIndicator(view.getImportingMessage());
        examplesService.call((WorkspaceProjectContextChangeEvent contextChangeEvent) -> {
                                 view.hideBusyIndicator();
                                 notificationEvent.fire(new NotificationEvent(view.getImportProjectsSuccessMessage(),
                                                                              NotificationEvent.NotificationType.SUCCESS));
                                 projectContextChangeEvent.fire(contextChangeEvent);
                             },
                             new HasBusyIndicatorDefaultErrorCallback(view)).setupExamples(new ExampleOrganizationalUnit(projectContext.getActiveOrganizationalUnit()
                                                                                .orElseThrow(() -> new IllegalStateException("Cannot setup examples without an active organizational unit."))
                                                                                .getName()),
                                                                                projects);
    }

    public void cancel() {
        libraryPlaces.goToLibrary();
    }

    @WorkbenchPartTitle
    public String getTitle() {
        return "Try Samples Screen";
    }

    @WorkbenchPartView
    public View getView() {
        return view;
    }
}


text:
use std::borrow::Cow;
use std::env;

/// Determines whether a `--flag` is present.
pub fn has_arg_flag(name: &str) -> bool {
    num_arg_flag(name) > 0
}

/// Determines how many times a `--flag` is present.
pub fn num_arg_flag(name: &str) -> usize {
    env::args().take_while(|val| val != "--").filter(|val| val == name).count()
}

/// Yields all values of command line flag `name` as `Ok(arg)`, and all other arguments except
/// the flag as `Err(arg)`. (The flag `name` itself is not yielded at all, only its values are.)
pub struct ArgSplitFlagValue<'a, I> {
    args: Option<I>,
    name: &'a str,
}

impl<'a, I: Iterator> ArgSplitFlagValue<'a, I> {
    fn new(args: I, name: &'a str) -> Self {
        Self { args: Some(args), name }
    }
}

impl<'s, I: Iterator<Item = Cow<'s, str>>> Iterator for ArgSplitFlagValue<'_, I> {
    // If the original iterator was all `Owned`, then we will only ever yield `Owned`
    // (so `into_owned()` is cheap).
    type Item = Result<Cow<'s, str>, Cow<'s, str>>;

    fn next(&mut self) -> Option<Self::Item> {
        let Some(args) = self.args.as_mut() else {
            // We already canceled this iterator.
            return None;
        };
        let arg = args.next()?;
        if arg == "--" {
            // Stop searching at `--`.
            self.args = None;
            return None;
        }
        // These branches cannot be merged if we want to avoid the allocation in the `Borrowed` branch.
        match &arg {
            Cow::Borrowed(arg) =>
                if let Some(suffix) = arg.strip_prefix(self.name) {
                    // Strip leading `name`.
                    if suffix.is_empty() {
                        // This argument is exactly `name`; the next one is the value.
                        return args.next().map(Ok);
                    } else if let Some(suffix) = suffix.strip_prefix('=') {
                        // This argument is `name=value`; get the value.
                        return Some(Ok(Cow::Borrowed(suffix)));
                    }
                },
            Cow::Owned(arg) =>
                if let Some(suffix) = arg.strip_prefix(self.name) {
                    // Strip leading `name`.
                    if suffix.is_empty() {
                        // This argument is exactly `name`; the next one is the value.
                        return args.next().map(Ok);
                    } else if let Some(suffix) = suffix.strip_prefix('=') {
                        // This argument is `name=value`; get the value. We need to do an allocation
                        // here as a `String` cannot be subsliced (what would the lifetime be?).
                        return Some(Ok(Cow::Owned(suffix.to_owned())));
                    }
                },
        }
        Some(Err(arg))
    }
}

impl<'a, I: Iterator<Item = String> + 'a> ArgSplitFlagValue<'a, I> {
    pub fn from_string_iter(
        args: I,
        name: &'a str,
    ) -> impl Iterator<Item = Result<String, String>> + 'a {
        ArgSplitFlagValue::new(args.map(Cow::Owned), name).map(|x| {
            match x {
                Ok(Cow::Owned(s)) => Ok(s),
                Err(Cow::Owned(s)) => Err(s),
                _ => panic!("iterator converted owned to borrowed"),
            }
        })
    }
}

impl<'x: 'a, 'a, I: Iterator<Item = &'x str> + 'a> ArgSplitFlagValue<'a, I> {
    pub fn from_str_iter(
        args: I,
        name: &'a str,
    ) -> impl Iterator<Item = Result<&'x str, &'x str>> + 'a {
        ArgSplitFlagValue::new(args.map(Cow::Borrowed), name).map(|x| {
            match x {
                Ok(Cow::Borrowed(s)) => Ok(s),
                Err(Cow::Borrowed(s)) => Err(s),
                _ => panic!("iterator converted borrowed to owned"),
            }
        })
    }
}

/// Yields all values of command line flag `name`.
pub struct ArgFlagValueIter;

impl ArgFlagValueIter {
    pub fn from_string_iter<'a, I: Iterator<Item = String> + 'a>(
        args: I,
        name: &'a str,
    ) -> impl Iterator<Item = String> + 'a {
        ArgSplitFlagValue::from_string_iter(args, name).filter_map(Result::ok)
    }
}

impl ArgFlagValueIter {
    pub fn from_str_iter<'x: 'a, 'a, I: Iterator<Item = &'x str> + 'a>(
        args: I,
        name: &'a str,
    ) -> impl Iterator<Item = &'x str> + 'a {
        ArgSplitFlagValue::from_str_iter(args, name).filter_map(Result::ok)
    }
}

/// Gets the values of a `--flag`.
pub fn get_arg_flag_values(name: &str) -> impl Iterator<Item = String> + '_ {
    ArgFlagValueIter::from_string_iter(env::args(), name)
}

/// Gets the value of a `--flag`.
pub fn get_arg_flag_value(name: &str) -> Option<String> {
    get_arg_flag_values(name).next()
}


text:
package com.macro.mall.dao;

import com.macro.mall.model.SmsCouponProductRelation;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 优惠券和商品关系自定义Dao
 * Created by macro on 2018/8/28.
 */
public interface SmsCouponProductRelationDao {
    /**
     * 批量创建
     */
    int insertList(@Param("list")List<SmsCouponProductRelation> productRelationList);
}


text:
% Licensed to the Apache Software Foundation (ASF) under one
% or more contributor license agreements.  See the NOTICE file
% distributed with this work for additional information
% regarding copyright ownership.  The ASF licenses this file
% to you under the Apache License, Version 2.0 (the
% "License"); you may not use this file except in compliance
% with the License.  You may obtain a copy of the License at

%   http://www.apache.org/licenses/LICENSE-2.0

% Unless required by applicable law or agreed to in writing,
% software distributed under the License is distributed on an
% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
% KIND, either express or implied.  See the License for the
% specific language governing permissions and limitations
% under the License.

!TEX root = ../design.tex

\chapter[k Nearest Neighbors]{k Nearest Neighbors}

\begin{moduleinfo}
\item[Authors] \href{mailto:okislal@pivotal.io}{Orhan Kislal}

\item[History]
	\begin{modulehistory}
		\item[v0.1] Initial version: knn and kd-tree.
	\end{modulehistory}
\end{moduleinfo}

% Abstract. What is the problem we want to solve?
\section{Introduction} % (fold)
\label{sec:knn_introduction}

\emph{Some notes and figures in this section are borrowed from \cite{medium_knn} and \cite{point_knn}}.

K-nearest neighbors (KNN) is one of the most commonly used learning
algorithms. The goal of knn is to find a number (k) of training data points
closest to the test point. These neighbors can be used to predict labels via
classification or regression.

KNN does not have a training phase like the most of learning techniques. It
does not create a model to generalize the data, instead the algorithm uses the
whole training dataset (or a specific subset of it).

KNN can be used for classification, the output is a class membership (a
discrete value). An object is classified by a majority vote of its neighbors,
with the object being assigned to the class most common among its k nearest
neighbors. It can also be used for regression, output is the value for the
object (predicts continuous values). This value is the average (or median) of
the values of its k nearest neighbors.

\section{Implementation Details}

The basic KNN implementation depends on the table join between the training dataset and the test dataset.

\begin{sql}
	(SELECT test_id,
            train_id,
            fn_dist(train_col_name, test_col_name) AS dist,
            label
    FROM train_table, test_table) AS knn_sub
\end{sql}

Once we have the distance between every train - test pair, the algorithm picks the k smallest values.

\begin{sql}
	SELECT row_number() OVER
        (PARTITION BY test_id ORDER BY dist) AS r,
        test_id,
        train_id,
        label
	FROM knn_sub
	WHERE r <= k
\end{sql}

Finally, the prediction is completed based on the labels of the selected
training points for each test point.

\section{Enabling KD-tree}

One of the major shortcomings of KNN is the fact that it is computationally
expensive. In addition, there is no training phase; which means every single
prediction will have to compute the full table join. One of the ways to
improve the performance is to reduce the search space for test points. Kd-tree
option is developed to enable trading the accuracy of the output with higher
performance by reducing the neighbor search space.

Kd-trees are used for organizing data in k dimensions. It is constructed like
a binary search tree where each level of the tree is using a specific
dimension for finding splits.

\begin{figure}[h]
	\centering
	\includegraphics[width=0.9\textwidth]{figures/2d_kdtree.pdf}
\caption{A 2D kd-tree of depth 3}
\label{kdd:2d_kdtree}
\end{figure}

A kd-tree is constructed by finding the median value of the data in a
particular dimension and separating the data into two sections based on this
value. This process is repeated a number of times to construct smaller
regions. Once the kd-tree is prepared, it can be used by any test point to
find its assigned region and this fragmentation can be used for limiting the
search space for nearest neighbors.

Once we have the kd-tree regions and their borders, we find the associated
regions for the test points. This gives us the first region to search for
nearest neighbors. In addition, we allow the user to request for multiple
regions to search. This means we have to decide which additional regions to
include in our search. We implemented a backtracking algorithm to find these
regions. The core idea is to find the closest border for each test point and
select the region on the other side of the border. Note that points that
reside in the same region might have different secondary (or tertiary, etc.)
regions. Consider the tree at Figure~\ref{kdd:2d_kdtree}. A test point at $<5
, 2>$ is in the same region as $<3 , 3.9>$. However, their closest borders and
the associated secondary regions are wildly different. In addition, consider
$<3 , 3.9>$ and $<6 , 3.9>$. They both have the same border as their closest
one ($y=4$). However, their closest regions do differ. To make sure that we
get the correct region, the following scheme is implemented. For a given point
$P$, we find the closest border, $dim[i] = x$ and $P$'s relative position to
it ($pos$ = $-1$ for lower and $+1$ for higher). We conjure a new point that
consists of the same values as the test point in every dimension except $i$.
For $dim[i]$, we set the value to $x-pos*\epsilon$. Finally, we use the
existing kd-tree to find this new point's assigned region. This region is our
expansion target for the point $P$. We repeat this process with the next
closest border as requested by the user.

The knn algorithm does not change significantly with the addition of regions.
Assuming that the training and test datasets have their region information
stored in the tables, the only necessary change is ensuring that the table
join uses these region ids to limit the search space.

\begin{sql}
	(SELECT test_id,
            train_id,
            fn_dist(train_col_name, test_col_name) AS dist,
            label
    FROM train_table, test_table
    WHERE train_table.region_id = test_table.region_id
    ) AS knn_sub
\end{sql}