text:
========
Research
========
This presents an overview of existing packages that might serve as inspiration
or possibly could be plugged in.

Validation
==========
An (incomplete) overview of existing validation packages (in alphabetical
order).

`Cerberus <http://docs.python-cerberus.org/>`_
----------------------------------------------
*Cerberus is a lightweight and extensible data validation library for Python.*

.. code-block:: python

    >>> schema = {'name': {'type': 'string'}}
    >>> v = Validator(schema)
    >>> document = {'name': 'john doe'}
    >>> v.validate(document)
    True

`Chainable Validators <https://github.com/Outernet-Project/chainable-validators>`_
----------------------------------------------------------------------------------

.. code-block:: python

    >>> import re
    >>> from validator import *
    >>> spec = {
    ...     'foo': [required, istype(int)],
    ...     'bar': [optional, match(re.compile(r'te.*')],
    ...     'baz': [optional, boolean],
    ... }

`Colander <http://docs.pylonsproject.org/projects/colander/>`_
--------------------------------------------------------------
*A serialization/deserialization/validation library for strings, mappings and
lists.*

.. code-block:: python

    import colander

    class Friend(colander.TupleSchema):
        rank = colander.SchemaNode(
            colander.Int(),
            validator=colander.Range(0, 9999)
        )
        name = colander.SchemaNode(colander.String())

    class Phone(colander.MappingSchema):
        location = colander.SchemaNode(
            colander.String(),
            validator=colander.OneOf(['home', 'work'])
        )
        number = colander.SchemaNode(colander.String())

    class Friends(colander.SequenceSchema):
        friend = Friend()

    class Phones(colander.SequenceSchema):
        phone = Phone()

    class Person(colander.MappingSchema):
        name = colander.SchemaNode(colander.String())
        age = colander.SchemaNode(
            colander.Int(),
            validator=colander.Range(0, 200)
        )
        friends = Friends()
        phones = Phones()

`django-nap <https://django-nap.readthedocs.io/>`
-------------------------------------------------

Schema generates from model:

.. code-block:: python

 class QuestionMapper(mapper.ModelMapper):
     class Meta:
         model = models.Question
         fields = '__all__'

Data binding::

	>>> q = Question.objects.first()
	>>> m = QuestionMapper(q)
	>>> m.question_text
	"What's new?"
	>>> m.pub_date
	'2017-06-17 05:30:58+00:00'

	>>> m.question_text = "So, what is new?"
	>>> q.question_text
	'So, what is new?'
	>>> m.pub_date = '1975-11-05 23:30:00'
	>>> q.pub_date
	datetime.datetime(1975, 11, 5, 23, 30)

`formencode.validator <http://www.formencode.org/en/latest/Validator.html>`_
----------------------------------------------------------------------------
*A validation library for Python.*

.. code-block:: python

    >>> class Registration(formencode.Schema):
    ...     first_name = validators.ByteString(not_empty=True)
    ...     last_name = validators.ByteString(not_empty=True)
    ...     email = validators.Email(resolve_domain=True)
    ...     username = formencode.All(
    ...         validators.PlainText(),
    ...         UniqueUsername()
    ...     )
    ...     password = SecurePassword()
    ...     password_confirm = validators.ByteString()
    ...     chained_validators = [
    ...         validators.FieldsMatch('password', 'password_confirm'),
    ...     ]

`Gladiator <https://github.com/laco/gladiator>`_
------------------------------------------------
*Gladiator is a Data Validation Framework for Python3*

.. code-block:: python

    import gladiator as gl

    registration_form_validator = (
        ('email', gl.required, gl.format_email),
        ('pw', gl.required, gl.length_min(5)),
        ('name', gl.required, gl.type_(str)),
        ('birth_year', gl.required, gl.type_(int), gl.value_max(2014 - 18)),
    )

    valid_test_data = {
        'email': 'test@example.com',
        'pw': 'password123',
        'name': 'Test Username',
        'birth_year': 1984,
    }

    result = gl.validate(registration_form_validator, valid_test_data)
    assert result.success

`good <https://github.com/kolypto/py-good>`_
--------------------------------------------
*Slim yet handsome validation library.*

.. code-block:: python

    from good import Schema, Entire

    def maxkeys(n):
        # Return a validator function
        def validator(d):
            # `d` is the dictionary.
            # Validate it
            assert len(d) <= 3, 'Dict size should be <= 3'
            # Return the value since all callable schemas should do that
            return d
        return validator

    schema = Schema({
        str: int,
        Entire: maxkeys(3),
    })

`incoming <https://incoming.readthedocs.org/>`_
-----------------------------------------------
*JSON validation framework for Python.*

.. code-block:: python

    >>> class AddressValidator(PayloadValidator):
    ...     street = datatypes.String()
    ...     country = datatypes.String()
    ...
    >>> class PersonValidator(PayloadValidator):
    ...     name = datatypes.String()
    ...     age = datatypes.Integer()
    ...     address = datatypes.JSON(AddressValidator)
    ...
    >>> PersonValidator().validate({
    ...     'name': 'Some name',
    ...     'age': 19,
    ...     'address': {'street': 'Brannan, SF', 'country': 'USA'},
    ... })
    (True, None)
    >>> PersonValidator().validate({
    ...     'name': 'Some name',
    ...     'age': 19,
    ...     'address': {'street': 'Brannan, SF', 'country': 0},
    ... })
    (False, {'address': ['Invalid data. Expected JSON.', {'country': ['Invalid
    data. Expected a string.']}]})

`Kanone <https://github.com/doncatnip/kanone>`_
-----------------------------------------------
*A general purpose validation library*

.. code-block:: python

    >>> from kanone import *
    >>> HelloSchema = Schema(
    ...     'nick', String() & Len(max=20),
    ...     'email', web.Email(),
    ...     'email_confirm', Match(Field('.email'), ignoreCase=True)
    ... )
    >>> context = HelloSchema.context({
    ...     'nick': 'bob',
    ...     'email': 'Bob@Some.Domain.Org',
    ...     'email_confirm': 'BOB@Some.domain.org',
    ... })
    >>> context('nick').result
    u'bob'
    >>> context('email').result
    u'Bob@some.domain.org'

`lasso <https://lasso.readthedocs.org/en/latest/>`_
---------------------------------------------------
*Lightweight module to define serializable, schema-validated classes*

.. code-block:: python

    >>> class Name(lasso.Schemed):
    ...     __schema__ = {"first": str, "family": str}
    ...
    >>> class User(lasso.Schemed):
    ...     __schema__ = {"name": Name, "email": str}
    ...
    >>> jdoe = User(
    ...     name=Name(first="John", family="Doe"),
    ...     email="j@doe.org"
    ... )

`marshmallow: simplified object serialization <https://marshmallow.readthedocs.org/>`_
--------------------------------------------------------------------------------------
*marshmallow is an ORM/ODM/framework-agnostic library for converting complex
datatypes, such as objects, to and from native Python datatypes.*

.. code-block:: python

    from marshmallow import Schema, fields

    class ArtistSchema(Schema):
        name = fields.Str()

    class AlbumSchema(Schema):
        title = fields.Str()
        artist = fields.Nested(ArtistSchema)

    schema = AlbumSchema()
    result = schema.dump(album)
    print(result.data)

* `django-rest-marshmallow <http://tomchristie.github.io/django-rest-marshmallow>`_:
  Marshmallow schemas for Django REST framework
* `marshmallow-form <https://github.com/podhmo/marshmallow-form>`_: a wrapper of
  marshmallow for form library like behavior
* `marshmallow-validators <https://marshmallow-validators.readthedocs.org/>`_:
  Use 3rd-party validators (e.g. from WTForms and colander) with marshmallow
* `webargs <https://webargs.readthedocs.org/>`_: A friendly library for parsing
  HTTP request arguments

`Naval <https://github.com/leforestier/naval>`_
-----------------------------------------------
*Python validation library with error messages in multiple languages and a
readable syntax.*

.. code-block:: python

    >>> from naval import *
    >>> # we're going to use the passlib library to encrypt passwords
    >>> from passlib.hash import bcrypt

    >>> registration_form = Schema(
            ['username', Type(str), Length(min=3, max=16)],
            ['password', Type(str)],
            ['password2'],
            [
                Assert(
                    (lambda d: d['password'] == d['password2']),
                    error_message = "Passwords don't match"
                )
            ],
            ['password', lambda s: s.encode('utf-8'), bcrypt.encrypt, Save],
            ['password2', Delete],
            ['email', Email]
        )

    >>> registration_form.validate({
            'email': 'the-king@example.com',
            'username': 'TheKing',
            'password': 'hackme',
            'password2': 'hackme',
        })
    {'email': 'the-king@example.com',
     'password': '$2a$12$JT2UlXP0REt3EX7kGIFGV.5uKPQJL4phDRpfcplW91sJAyB8RuKwm',
     'username': 'TheKing'}

`notario <http://notario.cafepais.com/>`_
-----------------------------------------
*Validation of Python dictionaries*

.. code-block:: python

    >>> data = {'main': {'foo': 'bar'}}
    >>> schema = ('main', MultiRecursive(('foo', 1), ('foo', 'bar')))
    >>> validate(data, schema)

`schema <https://github.com/keleshev/schema>`_
----------------------------------------------
*Schema validation just got Pythonic*

.. code-block:: python

    >>> from schema import Schema, And, Use, Optional

    >>> schema = Schema([{
    ...     'name': And(str, len),
    ...     'age':  And(Use(int), lambda n: 18 <= n <= 99),
    ...     Optional('sex'): And(
    ...         str, Use(str.lower), lambda s: s in ('male', 'female')
    ...     )
    ... }])

    >>> data = [
    ...     {'name': 'Sue', 'age': '28', 'sex': 'FEMALE'},
    ...     {'name': 'Sam', 'age': '42'},
    ...     {'name': 'Sacha', 'age': '20', 'sex': 'Male'},
    ... ]

    >>> validated = schema.validate(data)

    >>> assert validated == [
    ...     {'name': 'Sue', 'age': 28, 'sex': 'female'},
    ...     {'name': 'Sam', 'age': 42},
    ...     {'name': 'Sacha', 'age' : 20, 'sex': 'male'},
    ... ]

`Schematics <https://schematics.readthedocs.org/>`_
---------------------------------------------------
*Python Data Structures for Humans™.*

.. code-block:: python

    >>> from schematics.models import Model
    >>> from schematics.types import StringType
    >>> class Person(Model):
    ...     name = StringType()
    ...     bio = StringType(required=True)
    ...
    >>> p = Person()
    >>> p.name = 'Paul Eipper'
    >>> p.validate()
    Traceback (most recent call last):
    ...
    ModelValidationError: {'bio': [u'This field is required.']}

`sigma.core <https://github.com/pysigma/core>`_
-----------------------------------------------
*sigma.core is a validation framework.*

.. code-block:: python

    from sigma.core import Model, ErrorContainer, asdict, validate
    from sigma.standard import Field

    class User(Model):
        id = Field(type=int, size=(5, 10))
        password = Field(type=str, length=(8, 15))

    user = User()
    user.id = 5
    user.password = "12345678"
    asdict(user)  # {"id": 5, "password": "12345678"}

`val <https://github.com/thisfred/val>`_
----------------------------------------
*A validator for arbitrary Python objects.*

.. code-block:: python

    >>> from val import Schema
    >>> sub_schema = Schema({'foo': str, str: int})
    >>> schema = Schema({
    ...     'key1': sub_schema,
    ...     'key2': sub_schema,
    ...     str: sub_schema,
    ... })

    >>> schema.validates({
    ...     'key1': {'foo': 'bar'},
    ...     'key2': {'foo': 'qux', 'baz': 43},
    ...     'whatever': {'foo': 'doo', 'fsck': 22, 'tsk': 2992},
    ... })
    True

`valhalla <https://github.com/petermelias/valhalla>`_
-----------------------------------------------------
*Minimalist validation library with focus on API brevity and simplicity. 40+
filters primitive and composed.*

.. code-block:: python

    my_definition = {
        # email address with alternate name
        'email': ['require', ('alt', 'email_address'), 'email'],
        # age must be numeric between 13 and 100
        'age': ['require', 'numeric', ('range', 13, 100)],
        'password': [('text', 10, 50)],
        'password_confirm': [('match', 'password')]
    }

    s = Schema.from_dict(my_definition)
    s.validate(some_data) # Bam!

`valideer <https://github.com/podio/valideer>`_
-----------------------------------------------
*Lightweight data validation and adaptation Python library.*

.. code-block:: python

    >>> import valideer as V
    >>> product_schema = {
    ...     "+id": "number",
    ...     "+name": "string",
    ...     "+price": V.Range("number", min_value=0),
    ...     "tags": ["string"],
    ...     "stock": {
    ...         "warehouse": "number",
    ...         "retail": "number",
    ...     },
    ... }
    >>> validator = V.parse(product_schema)

`Validation <https://validation-py.readthedocs.org/>`_
------------------------------------------------------
*Validation is a small python library to validate python data structures.*

.. code-block:: python

    import validation

    # Build the validation model

    user_validator = validation.Dict()
    user_validator.required['_id'] = validation.StringUUID()
    user_validator.required['name'] = validation.String()
    user_validator.required['gender'] = validation.Choice(
        choices=['male', 'female']
    )
    hobbies = validation.List()
    hobbies.validator = validation.String()
    user_validator.optional['hobbies'] = validation.List()

    # two valid user objects

    john = {
        '_id': 'e7a5ff1c-ee5e-4ca9-a3d3-0106dd826dcd',
        'name': 'John',
        'gender': 'male',
        'hobbies:': [
            'python',
            'blarg',
            'blub'
        ],
    }

    paula = {
        '_id': 'e7a5ff1c-ee5e-4ca9-a3d3-0106dd826dcd',
        'name': 'Paula',
        'gender': 'female',
    }

    # an not valid one

    weirdo = {
        '_id': 'e7a5ff1c-ee5e-4ca9-a3d3-0106dd826dcd',
        'name': 'Weirdo',
        'gender': 'all of them',
        'hobbies:': [
            'mitosis',
        ],
    }

    for user in [john, paula, weirdo]:
        try:
            # None is returned of the user is valid
            user_validator.validate(john)
        except validation.ValidationError as err:
            # a exception is raised, if the object is invalid
            # the exception message contains the first failed element
            print(err)

`Validator <https://validatorpy.readthedocs.org/>`_
---------------------------------------------------
*A library for validating that dictionary values meet certain sets of
parameters. Much like form validators, but for dicts.*

.. code-block:: python

    from validator import Required, Not, Truthy, Blank, Range, Equals, In, validate

    # let's say that my dictionary needs to meet the following rules...
    rules = {
        "foo": [Required, Equals(123)],
        "bar": [Required, Truthy()],
        "baz": [In(["spam", "eggs", "bacon"])],
        "qux": [Not(Range(1, 100))], # by default, Range is inclusive
    }

    # then this following dict would pass:
    passes = {
        "foo": 123,
        "bar": True, # or a non-empty string, or a non-zero int, etc...
        "baz": "spam",
        "qux": 101,
    }
    print validate(rules, passes)
    # (True, {})

    # but this one would fail
    fails = {
        "foo": 321,
        "bar": False, # or 0, or [], or an empty string, etc...
        "baz": "barf",
        "qux": 99,
    }
    print validate(rules, fails)
    # (False,
    #  {
    #  'foo': ["must be equal to '123'"],
    #  'bar': ['must be True-equivalent value'],
    #  'baz': ["must be one of ['spam', 'eggs', 'bacon']"],
    #  'qux': ['must not fall between 1 and 100']
    #  })

`Validators <https://validators.readthedocs.org/>`_
---------------------------------------------------
*Python Data Validation for Humans™.*

.. code-block:: python

    >>> import validators

    >>> validators.email('someone@example.com')
    True

`voluptuous <https://github.com/alecthomas/voluptuous>`_
--------------------------------------------------------
*Voluptuous, despite the name, is a Python data validation library. It is
primarily intended for validating data coming into Python as JSON, YAML, etc.*

.. code-block:: python

    >>> from voluptuous import Required, All, Length, Range
    >>> schema = Schema({
    ...   Required('q'): All(str, Length(min=1)),
    ...   Required('per_page', default=5): All(int, Range(min=1, max=20)),
    ...   'page': All(int, Range(min=0)),
    ... })

`WTForms <https://wtforms.readthedocs.org/>`_
---------------------------------------------
*A flexible forms validation and rendering library for Python.*

.. code-block:: python

    from wtforms import Form, BooleanField, StringField, validators

    class RegistrationForm(Form):
        username = StringField(
            'Username', [validators.Length(min=4, max=25)]
        )
        email = StringField(
            'Email Address', [validators.Length(min=6, max=35)]
        )
        accept_rules = BooleanField(
            'I accept the site rules', [validators.InputRequired()]
        )

    def register(request):
        form = RegistrationForm(request.POST)
        if request.method == 'POST' and form.validate():
            user = User()
            user.username = form.username.data
            user.email = form.email.data
            user.save()
            redirect('register')
        return render_response('register.html', form=form)


text:
For the report and documentation of the project, check the file `report.pdf`

There is also the presentation we gave at the file `presentation.pdf`

## Building

~~~
runghc Setup.lhs configure
runghc Setup.lhs build
runghc Setup.lhs install
~~~

# Before running

You have to fetch the the entire hackage repository and its activity log. You can automatically do that with:

~~~
gpah --fetch
~~~

## Running the analysis

After building the program, run it with

`gpah args`

~~~
Generic Programming Use in Hackage Project v0.0.1

gpah [OPTIONS]

Common flags:
     --fetch                Fetch the Hackage archive tarball and Hackage
                            activity log
  -d --deriving[=FILE]      Run the deriving analysis and output it to the
                            specified file
  -f --function[=FILE]      Run the function analysis and output it to the
                            specified file
  -u --uniplate[=FILE]      Run the uniplate analysis and output it to the
                            specified file
  -h --misc_hackage[=FILE]  Print general analysis info or output it to the
                            specified file
  -t --misc_date[=FILE]     Get syb+uniplate date info and output it to the
                            specified file (implies --misc_hackage)
     --hackage-dir=DIR      Set the hackage archive directory
     --hackage-log=FILE     Set the hackage archive log file
  -c --cpp[=FILE]           Run preprocessing in hackage that yields an
                            analysis with less failed-to-parse modules
  -i --interpret[=FILE]     Do type-checking interpretation on modules that
                            depend on SYB or Uniplate
  -e --derive[=FILE]        Do analysis on packages that build on derive
  -? --help                 Display help message
  -V --version              Print version information
~~~

For a detailed description of the accepted arguments run:

`gpah --help`

redpajama_set_name: RedPajamaGithub


text:
package org.hoteia.qalingo.core.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.hoteia.qalingo.core.dao.RuleReferentialDao;
import org.hoteia.qalingo.core.domain.AbstractRuleReferential;
import org.hoteia.qalingo.core.service.RuleReferentialService;

@Service("ruleReferentialService")
@Transactional
public class RuleReferentialServiceImpl implements RuleReferentialService {

	@Autowired
	private RuleReferentialDao ruleReferentialDao;

	public AbstractRuleReferential getRuleReferentialByRuleType(String ruleType) {
		return ruleReferentialDao.getRuleReferentialByRuleType(ruleType);
	}

	public AbstractRuleReferential getRuleReferentialByCode(String code) {
		return ruleReferentialDao.getRuleReferentialByCode(code);
	}

	public List<AbstractRuleReferential> findRuleReferentials() {
		return ruleReferentialDao.findRuleReferentials();
	}

	public void saveRuleReferential(AbstractRuleReferential ruleReferential) {
		ruleReferentialDao.saveRuleReferential(ruleReferential);
	}

	public void deleteRuleReferential(AbstractRuleReferential ruleReferential) {
		ruleReferentialDao.deleteRuleReferential(ruleReferential);
	}

}


text: Platform whats helps make and manage testAB in your application.


text:
#ifndef SkTypeface_mac_DEFINED
#define SkTypeface_mac_DEFINED

#include "SkTypeface.h"
#include <Carbon/Carbon.h>

/**
 *  Like the other Typeface create methods, this returns a new reference to the
 *  corresponding typeface for the specified CTFontRef. The caller must call
 *  unref() when it is finished.
 */
SK_API extern SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef);

#endif


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

import com.facebook.presto.testing.MaterializedResult;
import com.facebook.presto.testing.MaterializedRow;
import com.facebook.presto.testing.QueryRunner;
import com.facebook.presto.tests.AbstractTestIntegrationSmokeTest;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.BaseEncoding;
import io.airlift.tpch.TpchTable;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.intellij.lang.annotations.Language;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Map;

import static com.facebook.presto.common.type.BigintType.BIGINT;
import static com.facebook.presto.common.type.VarcharType.VARCHAR;
import static com.facebook.presto.elasticsearch.ElasticsearchQueryRunner.createElasticsearchQueryRunner;
import static com.facebook.presto.elasticsearch.EmbeddedElasticsearchNode.createEmbeddedElasticsearchNode;
import static com.facebook.presto.testing.MaterializedResult.resultBuilder;
import static com.facebook.presto.testing.assertions.Assert.assertEquals;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.elasticsearch.client.Requests.indexAliasesRequest;
import static org.elasticsearch.client.Requests.refreshRequest;

@Test(singleThreaded = true)
public class TestElasticsearchIntegrationSmokeTest
        extends AbstractTestIntegrationSmokeTest
{
    private EmbeddedElasticsearchNode embeddedElasticsearchNode;

    @Override
    protected QueryRunner createQueryRunner()
            throws Exception
    {
        embeddedElasticsearchNode = createEmbeddedElasticsearchNode();
        return createElasticsearchQueryRunner(embeddedElasticsearchNode, TpchTable.getTables());
    }

    @AfterClass(alwaysRun = true)
    public final void destroy()
            throws IOException
    {
        embeddedElasticsearchNode.close();
    }

    @Test
    public void testSelectAll()
    {
        // List columns explicitly, as there's no defined order in Elasticsearch
        assertQuery("SELECT orderkey, custkey, orderstatus, totalprice, orderdate, orderpriority, clerk, shippriority, comment  FROM orders");
    }

    @Test
    public void testRangePredicate()
    {
        // List columns explicitly, as there's no defined order in Elasticsearch
        assertQuery("" +
                "SELECT orderkey, custkey, orderstatus, totalprice, orderdate, orderpriority, clerk, shippriority, comment " +
                "FROM orders " +
                "WHERE orderkey BETWEEN 10 AND 50");
    }

    @Test
    public void testCountAll()
    {
        assertQuery("SELECT COUNT(*) FROM orders");
        assertQuery("SELECT count(*) FROM orders WHERE orderkey > 10");
        assertQuery("SELECT count(*) FROM (SELECT * FROM orders LIMIT 10)");
        assertQuery("SELECT count(*) FROM (SELECT * FROM orders WHERE orderkey > 10 LIMIT 10)");
    }

    @Test
    public void testMultipleRangesPredicate()
    {
        assertQuery("" +
                "SELECT orderkey, custkey, orderstatus, totalprice, orderdate, orderpriority, clerk, shippriority, comment " +
                "FROM orders " +
                "WHERE orderkey BETWEEN 10 AND 50 OR orderkey BETWEEN 100 AND 150");
    }

    @Test
    @Override
    public void testDescribeTable()
    {
        MaterializedResult actualColumns = computeActual("DESC orders").toTestTypes();
        MaterializedResult.Builder builder = resultBuilder(getQueryRunner().getDefaultSession(), VARCHAR, VARCHAR, VARCHAR, VARCHAR);
        for (MaterializedRow row : actualColumns.getMaterializedRows()) {
            builder.row(row.getField(0), row.getField(1), "", "");
        }
        MaterializedResult actualResult = builder.build();
        builder = resultBuilder(getQueryRunner().getDefaultSession(), VARCHAR, VARCHAR, VARCHAR, VARCHAR);
        MaterializedResult expectedColumns = builder
                .row("clerk", "varchar", "", "")
                .row("comment", "varchar", "", "")
                .row("custkey", "bigint", "", "")
                .row("orderdate", "timestamp", "", "")
                .row("orderkey", "bigint", "", "")
                .row("orderpriority", "varchar", "", "")
                .row("orderstatus", "varchar", "", "")
                .row("shippriority", "bigint", "", "")
                .row("totalprice", "real", "", "")
                .build();
        assertEquals(actualResult, expectedColumns, format("%s != %s", actualResult, expectedColumns));
    }

    @Test
    public void testShowCreateTable()
    {
        assertThat(computeActual("SHOW CREATE TABLE orders").getOnlyValue())
                .isEqualTo("CREATE TABLE elasticsearch.tpch.orders (\n" +
                        "   \"clerk\" varchar,\n" +
                        "   \"comment\" varchar,\n" +
                        "   \"custkey\" bigint,\n" +
                        "   \"orderdate\" timestamp,\n" +
                        "   \"orderkey\" bigint,\n" +
                        "   \"orderpriority\" varchar,\n" +
                        "   \"orderstatus\" varchar,\n" +
                        "   \"shippriority\" bigint,\n" +
                        "   \"totalprice\" real\n" +
                        ")");
    }

    @Test
    public void testArrayFields()
    {
        String indexName = "test_arrays";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc", "" +
                                "{" +
                                "  \"_meta\": {" +
                                "    \"presto\": {" +
                                "      \"a\": {" +
                                "        \"b\": {" +
                                "          \"y\": {" +
                                "            \"isArray\": true" +
                                "          }" +
                                "        }" +
                                "      }," +
                                "      \"c\": {" +
                                "        \"f\": {" +
                                "          \"g\": {" +
                                "            \"isArray\": true" +
                                "          }," +
                                "          \"isArray\": true" +
                                "        }" +
                                "      }," +
                                "      \"j\": {" +
                                "        \"isArray\": true" +
                                "      }," +
                                "      \"k\": {" +
                                "        \"isArray\": true" +
                                "      }" +
                                "    }" +
                                "  }," +
                                "  \"properties\":{" +
                                "    \"a\": {" +
                                "      \"type\": \"object\"," +
                                "      \"properties\": {" +
                                "        \"b\": {" +
                                "          \"type\": \"object\"," +
                                "          \"properties\": {" +
                                "            \"x\": {" +
                                "              \"type\": \"integer\"" +
                                "            }," +
                                "            \"y\": {" +
                                "              \"type\": \"keyword\"" +
                                "            }" +
                                "          } " +
                                "        }" +
                                "      }" +
                                "    }," +
                                "    \"c\": {" +
                                "      \"type\": \"object\"," +
                                "      \"properties\": {" +
                                "        \"d\": {" +
                                "          \"type\": \"keyword\"" +
                                "        }," +
                                "        \"e\": {" +
                                "          \"type\": \"keyword\"" +
                                "        }," +
                                "        \"f\": {" +
                                "          \"type\": \"object\"," +
                                "          \"properties\": {" +
                                "            \"g\": {" +
                                "              \"type\": \"integer\"" +
                                "            }," +
                                "            \"h\": {" +
                                "              \"type\": \"integer\"" +
                                "            }" +
                                "          } " +
                                "        }" +
                                "      }" +
                                "    }," +
                                "    \"i\": {" +
                                "      \"type\": \"long\"" +
                                "    }," +
                                "    \"j\": {" +
                                "      \"type\": \"long\"" +
                                "    }," +
                                "    \"k\": {" +
                                "      \"type\": \"long\"" +
                                "    }" +
                                "  }" +
                                "}",
                        XContentType.JSON)
                .get();

        index(indexName, ImmutableMap.<String, Object>builder()
                .put("a", ImmutableMap.<String, Object>builder()
                        .put("b", ImmutableMap.<String, Object>builder()
                                .put("x", 1)
                                .put("y", ImmutableList.<String>builder()
                                        .add("hello")
                                        .add("world")
                                        .build())
                                .build())
                        .build())
                .put("c", ImmutableMap.<String, Object>builder()
                        .put("d", "foo")
                        .put("e", "bar")
                        .put("f", ImmutableList.<Map<String, Object>>builder()
                                .add(ImmutableMap.<String, Object>builder()
                                        .put("g", ImmutableList.<Integer>builder()
                                                .add(10)
                                                .add(20)
                                                .build())
                                        .put("h", 100)
                                        .build())
                                .add(ImmutableMap.<String, Object>builder()
                                        .put("g", ImmutableList.<Integer>builder()
                                                .add(30)
                                                .add(40)
                                                .build())
                                        .put("h", 200)
                                        .build())
                                .build())
                        .build())
                .put("j", ImmutableList.<Long>builder()
                        .add(50L)
                        .add(60L)
                        .build())
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT a.b.y[1], c.f[1].g[2], c.f[2].g[1], j[2], k[1] FROM test_arrays",
                "VALUES ('hello', 20, 30, 60, NULL)");
    }

    @Test
    public void testEmptyObjectFields()
    {
        String indexName = "emptyobject";
        index(indexName, ImmutableMap.<String, Object>builder()
                .put("name", "stringfield")
                .put("emptyobject", ImmutableMap.of())
                .put("fields.fielda", 32)
                .put("fields.fieldb", ImmutableMap.of())
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT name, fields.fielda FROM emptyobject",
                "VALUES ('stringfield', 32)");
    }

    @Test
    public void testNullPredicate()
    {
        String indexName = "null_predicate1";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc",
                        "null_keyword", "type=keyword",
                        "custkey", "type=keyword")
                .get();
        index(indexName, ImmutableMap.<String, Object>builder()
                .put("null_keyword", 32)
                .put("custkey", 1301)
                .build());
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQueryReturnsEmptyResult("SELECT * FROM null_predicate1 WHERE null_keyword IS NULL");
        assertQueryReturnsEmptyResult("SELECT * FROM null_predicate1 WHERE null_keyword = '10' OR null_keyword IS NULL");

        assertQuery("SELECT custkey, null_keyword FROM null_predicate1 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301, 32)");
        assertQuery("SELECT custkey FROM null_predicate1 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301)");

        // not null filter
        // filtered column is selected
        assertQuery("SELECT custkey, null_keyword FROM null_predicate1 WHERE null_keyword IS NOT NULL", "VALUES (1301, 32)");
        assertQuery("SELECT custkey, null_keyword FROM null_predicate1 WHERE null_keyword = '32' OR null_keyword IS NOT NULL", "VALUES (1301, 32)");

        // filtered column is not selected
        assertQuery("SELECT custkey FROM null_predicate1 WHERE null_keyword = '32' OR null_keyword IS NOT NULL", "VALUES (1301)");

        indexName = "null_predicate2";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc",
                        "null_keyword", "type=keyword",
                        "custkey", "type=keyword")
                .get();
        index(indexName, ImmutableMap.<String, Object>builder()
                .put("custkey", 1301)
                .build());
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        // not null filter
        assertQueryReturnsEmptyResult("SELECT * FROM null_predicate2 WHERE null_keyword IS NOT NULL");
        assertQueryReturnsEmptyResult("SELECT * FROM null_predicate2 WHERE null_keyword = '10' OR null_keyword IS NOT NULL");

        // filtered column is selected
        assertQuery("SELECT custkey, null_keyword FROM null_predicate2 WHERE null_keyword IS NULL", "VALUES (1301, NULL)");
        assertQuery("SELECT custkey, null_keyword FROM null_predicate2 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301, NULL)");

        // filtered column is not selected
        assertQuery("SELECT custkey FROM null_predicate2 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301)");

        index(indexName, ImmutableMap.<String, Object>builder()
                .put("null_keyword", 32)
                .put("custkey", 1302)
                .build());
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery("SELECT custkey, null_keyword FROM null_predicate2 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301, NULL), (1302, 32)");
        assertQuery("SELECT custkey FROM null_predicate2 WHERE null_keyword = '32' OR null_keyword IS NULL", "VALUES (1301), (1302)");
    }

    @Test
    public void testNestedFields()
    {
        String indexName = "data";
        index(indexName, ImmutableMap.<String, Object>builder()
                .put("name", "nestfield")
                .put("fields.fielda", 32)
                .put("fields.fieldb", "valueb")
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT name, fields.fielda, fields.fieldb FROM data",
                "VALUES ('nestfield', 32, 'valueb')");
    }

    @Test
    public void testNestedVariants()
    {
        String indexName = "nested_variants";

        index(indexName,
                ImmutableMap.of("a",
                        ImmutableMap.of("b",
                                ImmutableMap.of("c",
                                        "value1"))));

        index(indexName,
                ImmutableMap.of("a.b",
                        ImmutableMap.of("c",
                                "value2")));

        index(indexName,
                ImmutableMap.of("a",
                        ImmutableMap.of("b.c",
                                "value3")));

        index(indexName,
                ImmutableMap.of("a.b.c", "value4"));

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT a.b.c FROM nested_variants",
                "VALUES 'value1', 'value2', 'value3', 'value4'");
    }

    @Test
    public void testDataTypes()
    {
        String indexName = "types";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc",
                        "boolean_column", "type=boolean",
                        "float_column", "type=float",
                        "double_column", "type=double",
                        "integer_column", "type=integer",
                        "long_column", "type=long",
                        "keyword_column", "type=keyword",
                        "text_column", "type=text",
                        "binary_column", "type=binary",
                        "timestamp_column", "type=date",
                        "ipv4_column", "type=ip",
                        "ipv6_column", "type=ip")
                .get();

        index(indexName, ImmutableMap.<String, Object>builder()
                .put("boolean_column", true)
                .put("float_column", 1.0f)
                .put("double_column", 1.0d)
                .put("integer_column", 1)
                .put("long_column", 1L)
                .put("keyword_column", "cool")
                .put("text_column", "some text")
                .put("binary_column", new byte[] {(byte) 0xCA, (byte) 0xFE})
                .put("timestamp_column", 0)
                .put("ipv4_column", "192.0.2.4")
                .put("ipv6_column", "2001:db8:0:1:1:1:1:1")
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();
        MaterializedResult rows = computeActual("" +
                "SELECT " +
                "boolean_column, " +
                "float_column, " +
                "double_column, " +
                "integer_column, " +
                "long_column, " +
                "keyword_column, " +
                "text_column, " +
                "binary_column, " +
                "timestamp_column, " +
                "ipv4_column, " +
                "ipv6_column " +
                "FROM types");

        MaterializedResult expected = resultBuilder(getSession(), rows.getTypes())
                .row(true, 1.0f, 1.0d, 1, 1L, "cool", "some text", new byte[] {(byte) 0xCA, (byte) 0xFE},
                        LocalDateTime.of(1970, 1, 1, 0, 0), "192.0.2.4", "2001:db8:0:1:1:1:1:1")
                .build();

        assertEquals(rows.getMaterializedRows(), expected.getMaterializedRows());
    }

    @Test
    public void testFilters()
    {
        String indexName = "filter_pushdown";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc",
                        "boolean_column", "type=boolean",
                        "byte_column", "type=byte",
                        "short_column", "type=short",
                        "integer_column", "type=integer",
                        "long_column", "type=long",
                        "float_column", "type=float",
                        "double_column", "type=double",
                        "keyword_column", "type=keyword",
                        "text_column", "type=text",
                        "binary_column", "type=binary",
                        "timestamp_column", "type=date",
                        "ipv4_column", "type=ip",
                        "ipv6_column", "type=ip")
                .get();

        index(indexName, ImmutableMap.<String, Object>builder()
                .put("boolean_column", true)
                .put("byte_column", 1)
                .put("short_column", 2)
                .put("integer_column", 3)
                .put("long_column", 4L)
                .put("float_column", 1.0f)
                .put("double_column", 1.0d)
                .put("keyword_column", "cool")
                .put("text_column", "some text")
                .put("binary_column", new byte[] {(byte) 0xCA, (byte) 0xFE})
                .put("timestamp_column", 1569888000000L)
                .put("ipv4_column", "192.0.2.4")
                .put("ipv6_column", "2001:db8:0:1:1:1:1:1")
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        // boolean
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE boolean_column = true", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE boolean_column = false", "VALUES 0");

        // tinyint
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column = 1", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column = 0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column > 1", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column < 1", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column > 0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE byte_column < 10", "VALUES 1");

        // smallint
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column = 2", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column > 2", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column < 2", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column = 0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column > 0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE short_column < 10", "VALUES 1");

        // integer
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column = 3", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column > 3", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column < 3", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column = 0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column > 0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE integer_column < 10", "VALUES 1");

        // bigint
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column = 4", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column > 4", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column < 4", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column = 0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column > 0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE long_column < 10", "VALUES 1");

        // real
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column = 1.0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column > 1.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column < 1.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column = 0.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column > 0.0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE float_column < 10.0", "VALUES 1");

        // double
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column = 1.0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column > 1.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column < 1.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column = 0.0", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column > 0.0", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE double_column < 10.0", "VALUES 1");

        // varchar
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE keyword_column = 'cool'", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE keyword_column = 'bar'", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE text_column = 'some'", "VALUES 0");

        // timestamp
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column = TIMESTAMP '2019-10-01 00:00:00'", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column > TIMESTAMP '2019-10-01 00:00:00'", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column < TIMESTAMP '2019-10-01 00:00:00'", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column = TIMESTAMP '2019-10-02 00:00:00'", "VALUES 0");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column > TIMESTAMP '2001-01-01 00:00:00'", "VALUES 1");
        assertQuery("SELECT count(*) FROM filter_pushdown WHERE timestamp_column < TIMESTAMP '2030-01-01 00:00:00'", "VALUES 1");

        // ipaddress
        assertQuery("SELECT count(ipv4_column) FROM filter_pushdown", "VALUES 1");
        assertQuery("SELECT count(ipv6_column) FROM filter_pushdown", "VALUES 1");
    }

    @Test
    public void testDataTypesNested()
    {
        String indexName = "types_nested";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc", "" +
                                "{ " +
                                "    \"properties\": {\n" +
                                "        \"field\": {\n" +
                                "            \"properties\": {\n" +
                                "                \"boolean_column\":   { \"type\": \"boolean\" },\n" +
                                "                \"float_column\":     { \"type\": \"float\" },\n" +
                                "                \"double_column\":    { \"type\": \"double\" },\n" +
                                "                \"integer_column\":   { \"type\": \"integer\" },\n" +
                                "                \"long_column\":      { \"type\": \"long\" },\n" +
                                "                \"keyword_column\":   { \"type\": \"keyword\" },\n" +
                                "                \"text_column\":      { \"type\": \"text\" },\n" +
                                "                \"binary_column\":    { \"type\": \"binary\" },\n" +
                                "                \"timestamp_column\": { \"type\": \"date\" },\n" +
                                "                \"ipv4_column\":      { \"type\": \"ip\" },\n" +
                                "                \"ipv6_column\":      { \"type\": \"ip\" }\n" +
                                "            }\n" +
                                "        }\n" +
                                "    }" +
                                "}\n",
                        XContentType.JSON)
                .get();

        index(indexName, ImmutableMap.of(
                "field",
                ImmutableMap.<String, Object>builder()
                        .put("boolean_column", true)
                        .put("float_column", 1.0f)
                        .put("double_column", 1.0d)
                        .put("integer_column", 1)
                        .put("long_column", 1L)
                        .put("keyword_column", "cool")
                        .put("text_column", "some text")
                        .put("binary_column", new byte[] {(byte) 0xCA, (byte) 0xFE})
                        .put("timestamp_column", 0)
                        .put("ipv4_column", "192.0.2.4")
                        .put("ipv6_column", "2001:db8:0:1:1:1:1:1")
                        .build()));

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        MaterializedResult rows = computeActual("" +
                "SELECT " +
                "field.boolean_column, " +
                "field.float_column, " +
                "field.double_column, " +
                "field.integer_column, " +
                "field.long_column, " +
                "field.keyword_column, " +
                "field.text_column, " +
                "field.binary_column, " +
                "field.timestamp_column, " +
                "field.ipv4_column, " +
                "field.ipv6_column " +
                "FROM types_nested");

        MaterializedResult expected = resultBuilder(getSession(), rows.getTypes())
                .row(true, 1.0f, 1.0d, 1, 1L, "cool", "some text", new byte[] {(byte) 0xCA, (byte) 0xFE},
                        LocalDateTime.of(1970, 1, 1, 0, 0), "192.0.2.4", "2001:db8:0:1:1:1:1:1")
                .build();

        assertEquals(rows.getMaterializedRows(), expected.getMaterializedRows());
    }

    @Test
    public void testNestedTypeDataTypesNested()
    {
        String indexName = "nested_type_nested";

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc", "" +
                                "{ " +
                                "    \"properties\": {\n" +
                                "        \"nested_field\": {" +
                                "          \"type\":\"nested\"," +
                                "          \"properties\": {" +
                                "            \"boolean_column\":   { \"type\": \"boolean\" },\n" +
                                "            \"float_column\":     { \"type\": \"float\" },\n" +
                                "            \"double_column\":    { \"type\": \"double\" },\n" +
                                "            \"integer_column\":   { \"type\": \"integer\" }\n," +
                                "            \"long_column\":      { \"type\": \"long\" },\n" +
                                "            \"keyword_column\":   { \"type\": \"keyword\" },\n" +
                                "            \"text_column\":      { \"type\": \"text\" },\n" +
                                "            \"binary_column\":    { \"type\": \"binary\" },\n" +
                                "            \"timestamp_column\": { \"type\": \"date\" },\n" +
                                "            \"ipv4_column\":      { \"type\": \"ip\" },\n" +
                                "            \"ipv6_column\":      { \"type\": \"ip\" }\n" +
                                "            }\n" +
                                "        }\n" +
                                "    }" +
                                "}\n",
                        XContentType.JSON)
                .get();

        index(indexName, ImmutableMap.of(
                "nested_field",
                ImmutableMap.<String, Object>builder()
                        .put("boolean_column", true)
                        .put("float_column", 1.0f)
                        .put("double_column", 1.0d)
                        .put("integer_column", 1)
                        .put("long_column", 1L)
                        .put("keyword_column", "cool")
                        .put("text_column", "some text")
                        .put("binary_column", new byte[] {(byte) 0xCA, (byte) 0xFE})
                        .put("timestamp_column", 0)
                        .put("ipv4_column", "192.0.2.4")
                        .put("ipv6_column", "2001:db8:0:1:1:1:1:1")
                        .build()));

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        MaterializedResult rows = computeActual("" +
                "SELECT " +
                "nested_field.boolean_column, " +
                "nested_field.float_column, " +
                "nested_field.double_column, " +
                "nested_field.integer_column, " +
                "nested_field.long_column, " +
                "nested_field.keyword_column, " +
                "nested_field.text_column, " +
                "nested_field.binary_column, " +
                "nested_field.timestamp_column, " +
                "nested_field.ipv4_column, " +
                "nested_field.ipv6_column " +
                "FROM nested_type_nested");

        MaterializedResult expected = resultBuilder(getSession(), rows.getTypes())
                .row(true, 1.0f, 1.0d, 1, 1L, "cool", "some text", new byte[] {(byte) 0xCA, (byte) 0xFE},
                        LocalDateTime.of(1970, 1, 1, 0, 0), "192.0.2.4", "2001:db8:0:1:1:1:1:1")
                .build();

        assertEquals(rows.getMaterializedRows(), expected.getMaterializedRows());
    }

    @Test
    public void testQueryString()
    {
        MaterializedResult actual = computeActual("SELECT count(*) FROM \"orders: +packages -slyly\"");

        MaterializedResult expected = resultBuilder(getSession(), ImmutableList.of(BIGINT))
                .row(1639L)
                .build();

        assertEquals(actual, expected);
    }

    @Test
    public void testMixedCase()
    {
        String indexName = "mixed_case";
        index(indexName, ImmutableMap.<String, Object>builder()
                .put("Name", "john")
                .put("AGE", 32)
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT name, age FROM mixed_case",
                "VALUES ('john', 32)");

        assertQuery(
                "SELECT name, age FROM mixed_case WHERE name = 'john'",
                "VALUES ('john', 32)");
    }

    @Test
    public void testNumericKeyword()
            throws IOException
    {
        String indexName = "numeric_keyword";
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .prepareCreate(indexName)
                .addMapping("doc",
                        "numeric_column", "type=keyword")
                .get();

        index(indexName, ImmutableMap.<String, Object>builder()
                .put("numeric_column", 20)
                .build());

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest(indexName))
                .actionGet();

        assertQuery(
                "SELECT numeric_column FROM numeric_keyword",
                "VALUES 20");
        assertQuery(
                "SELECT numeric_column FROM numeric_keyword where numeric_column = '20'",
                "VALUES 20");
    }

    @Test
    public void testQueryStringError()
    {
        assertQueryFails("SELECT orderkey FROM \"orders: ++foo AND\"", "\\QFailed to parse query [ ++foo and]\\E");
        assertQueryFails("SELECT count(*) FROM \"orders: ++foo AND\"", "\\QFailed to parse query [ ++foo and]\\E");
    }

    @Test
    public void testAlias()
    {
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .aliases(indexAliasesRequest()
                        .addAliasAction(IndicesAliasesRequest.AliasActions.add()
                                .index("orders")
                                .alias("orders_alias")))
                .actionGet();

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest("orders_alias"))
                .actionGet();

        assertQuery(
                "SELECT count(*) FROM orders_alias",
                "SELECT count(*) FROM orders");

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .aliases(indexAliasesRequest()
                        .addAliasAction(IndicesAliasesRequest.AliasActions.remove()
                                .index("orders")
                                .alias("orders_alias")))
                .actionGet();
    }

    @Test(enabled = false)
    public void testMultiIndexAlias()
    {
        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .aliases(indexAliasesRequest()
                        .addAliasAction(IndicesAliasesRequest.AliasActions.add()
                                .index("nation")
                                .alias("multi_alias")))
                .actionGet();

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .aliases(indexAliasesRequest()
                        .addAliasAction(IndicesAliasesRequest.AliasActions.add()
                                .index("region")
                                .alias("multi_alias")))
                .actionGet();

        embeddedElasticsearchNode.getClient()
                .admin()
                .indices()
                .refresh(refreshRequest("multi_alias"))
                .actionGet();

        assertQuery(
                "SELECT count(*) FROM multi_alias",
                "SELECT (SELECT count(*) FROM region) + (SELECT count(*) FROM nation)");
    }

    private void index(String indexName, Map<String, Object> document)
    {
        embeddedElasticsearchNode.getClient()
                .prepareIndex(indexName, "doc")
                .setSource(document)
                .get();
    }

    @Test
    public void testPassthroughQuery()
    {
        @Language("JSON")
        String query = "{\n" +
                "    \"size\": 0,\n" +
                "    \"aggs\" : {\n" +
                "        \"max_orderkey\" : { \"max\" : { \"field\" : \"orderkey\" } },\n" +
                "        \"sum_orderkey\" : { \"sum\" : { \"field\" : \"orderkey\" } }\n" +
                "    }\n" +
                "}";

        assertQuery(
                format("WITH data(r) AS (" +
                        "   SELECT CAST(result AS ROW(aggregations ROW(max_orderkey ROW(value BIGINT), sum_orderkey ROW(value BIGINT)))) " +
                        "   FROM \"orders$query:%s\") " +
                        "SELECT r.aggregations.max_orderkey.value, r.aggregations.sum_orderkey.value " +
                        "FROM data", BaseEncoding.base32().encode(query.getBytes(UTF_8))),
                "VALUES (60000, 449872500)");

        assertQueryFails(
                "SELECT * FROM \"orders$query:invalid-base32-encoding\"",
                "Elasticsearch query for 'orders' is not base32-encoded correctly");
        assertQueryFails(
                format("SELECT * FROM \"orders$query:%s\"", BaseEncoding.base32().encode("invalid json".getBytes(UTF_8))),
                "Elasticsearch query for 'orders' is not valid JSON");
    }
}


text:
//using UnityEngine;
//using Stratus;
//using System.Collections.Generic;
//using System.Linq;
//using System;
//using Stratus.Utilities;

//namespace Stratus.Gameplay
//{

//		//------------------------------------------------------------------------/
//		// Methods
//		//------------------------------------------------------------------------/
//		///// <summary>
//		///// Finds all targets of a specified type available to this character within a specified range
//		///// </summary>
//		///// <param name="type"></param>
//		///// <param name="radius"></param>
//		///// <param name="state"></param>
//		///// <returns></returns>
//		//public static StratusCombatController[] FindTargetsOfTypeInWorld(StratusCombatController source, StratusCombat.TargetingParameters type, float radius = 20f, State state = State.Active)
//		//{
//		//	var hits = Physics.OverlapSphere(source.transform.position, radius);
//		//	var availableTargets = (from Collider hit in hits
//		//							where hit.GetComponent<StratusCombatController>()
//		//							select hit.GetComponent<StratusCombatController>()).ToArray();
//		//	return FindTargetsOfTypeInWorld(source, availableTargets, type, state);
//		//}

//		///// <summary>
//		///// Finds all targets of a specified type available to this character
//		///// </summary>
//		///// <param name="availableTargets"></param>
//		///// <param name="type"></param>
//		///// <param name="state"></param>
//		///// <returns></returns>
//		//public static StratusCombatController[] FindTargetsOfTypeInWorld(StratusCombatController source, StratusCombatController[] availableTargets, StratusCombat.TargetingParameters type, State state = State.Active)
//		//{
//		//	StratusCombatController[] targets = null;
//		//	if (type == StratusCombat.TargetingParameters.Self)
//		//	{
//		//		targets = new StratusCombatController[] { source };
//		//	}
//		//	else if (type == StratusCombat.TargetingParameters.Ally)
//		//	{
//		//		switch (source.faction)
//		//		{
//		//			case StratusCombatController.TargetType.Player:
//		//				targets = FilterTargets(availableTargets, TargetType.Player);
//		//				break;

//		//			case StratusCombatController.TargetType.Hostile:
//		//				targets = FilterTargets(availableTargets, TargetType.Hostile);
//		//				break;
//		//			case StratusCombatController.TargetType.Neutral:
//		//				targets = FilterTargets(availableTargets, TargetType.Hostile | TargetType.Player);
//		//				break;
//		//		}
//		//	}
//		//	// ENEMIES0
//		//	else if (type == StratusCombat.TargetingParameters.Enemy)
//		//	{
//		//		switch (source.faction)
//		//		{
//		//			case StratusCombatController.TargetType.Player:
//		//				targets = FilterTargets(availableTargets, TargetType.Hostile);
//		//				break;
//		//			case StratusCombatController.TargetType.Hostile:
//		//				targets = FilterTargets(availableTargets, TargetType.Player);
//		//				break;
//		//			case StratusCombatController.TargetType.Neutral:
//		//				targets = FilterTargets(availableTargets, TargetType.Hostile | TargetType.Player);
//		//				break;
//		//		}
//		//	}

//		//	return (from StratusCombatController controller in targets where controller.currentState == state select controller).ToArray();
//		//}

//		///// <summary>
//		/////
//		///// </summary>
//		///// <param name="availableTargets"></param>
//		///// <param name="faction"></param>
//		///// <returns></returns>
//		//public static StratusCombatController[] FilterTargets(StratusCombatController[] availableTargets, TargetType faction)
//		//{
//		//	return (from StratusCombatController target in availableTargets
//		//			where target.faction == faction
//		//			select target).ToArray();
//		//}

//		/*
//		 NOTE: The Combat Controller is purely-event driven. It's action cycle is defined as follows:
//		 * I.   SelectAction:  Asks the player/autonomous agent to pick an action. If an action was
//		 *                    successfully selected, it will be queued. Otherwise we try again.
//		 * II.  QueueEvent:    Adds an action to the character's queue, usually setting it as the current action.
//		 *                    The controller will now start updating that action.
//		 * III. StartedEvent: Once the action has determined the agent is within the specified range of its target,
//		 *                    it will start casting.
//		 * IV.  TriggerEvent:  Once the action has finished casting, it will be triggered.
//		 *                    After waiting a specified animation duration time, it will execute.
//		 * V.   ExecuteEvent:   At this point the action will send its according event to its specified target.
//		 * VI.  EndedEvent:    The action has finished executing. At this point, we start again from the top.
//		*/

//	}

//}


text:
"""
setup.py file for postscriptbarcode
"""

from distutils.command.build import build
from distutils.core import Command, Extension, setup

with open("../../../CHANGES", "r") as f:
    ver = f.readline().strip().replace("-", "")

class Test(Command):
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        import subprocess
        import sys

        errno = subprocess.call([sys.executable, "example.py"])
        raise SystemExit(errno)

postscriptbarcode_module = Extension(
    "_postscriptbarcode",
    sources=["postscriptbarcode.i"],
    include_dirs=["../../c"],
    libraries=["postscriptbarcode"],
    library_dirs=["../../c"],
)

build.sub_commands = [
    ("build_ext", build.has_ext_modules),
    ("build_py", build.has_pure_modules),
    ("build_clib", build.has_c_libraries),
    ("build_scripts", build.has_scripts),
]

setup(
    name="postscriptbarcode",
    version=ver,
    author="Terry Burton",
    author_email="tez@terryburton.co.uk",
    description="""Python binding for Barcode Writer in Pure PostScript""",
    url="https://bwipp.terryburton.co.uk",
    ext_modules=[postscriptbarcode_module],
    py_modules=["postscriptbarcode"],
    cmdclass={"test": Test},
)


text:
build = build

all: $(build)/Makefile
	cd $(build) && make

$(build)/Makefile: ./test/CMakeLists.txt
	mkdir -p $(build) && cd $(build) && cmake ../test -G"Unix Makefiles"

clean:
	$(MAKE) -C $(build) clean
	rm -rf $(build)

tests:
	octave -q ./test/test_vector_example.m
	octave -q ./test/test_eigen_vector_example.m
	octave -q ./test/test_eigen_matrix_example.m
	octave -q ./test/test_types.m


text:
ie::WavefrontObjectFileReader::WavefrontObjectFileReader(void) {}
ie::WavefrontObjectFileReader::WavefrontObjectFileReader(std::string filepath,
                                                         std::string filename)
{
  read(filepath, filename);
}

bool ie::WavefrontObjectFileReader::clear(void)
{
  filePackage.filename = "";
  filePackage.objects.clear();
  filePackage.objectGroups.clear();
  filePackage.materialGroups.clear();
  filePackage.smoothGroups.clear();
  filePackage.v.clear();
  filePackage.vt.clear();
  filePackage.vn.clear();
  filePackage.f.clear();
  filePackage.materialFilePackages.clear();
}

ie::WavefrontObjectFilePackage ie::WavefrontObjectFileReader::read(std::string filepath,
                                                                   std::string filename)
{
  hasQuads = false;
  std::vector<std::string> mtllib;
  std::ifstream objFile;
  objFile.open((filepath + filename).c_str());
  if (objFile.is_open())
  {
    clear();
    filePackage.filename = filename;
    filePackage.filepath = filepath;
    size_t indexOffset = 0;
    int noData = -1;
    std::string line;
    while (getline(objFile, line))
    {
      std::string command = split(line, ' ', 0);
      int tokenAmount = std::count(line.begin(), line.end(), ' ');

      if (command == "#") {continue;} //Comment
      else if (command == "") {continue;} //Blank Line

      else if (command == "mtllib")
      {
        for (int n = 1; n <= tokenAmount; n++)
        {
          std::string mtlFilename = split(line, ' ', n);
          mtllib.push_back(mtlFilename);
        }
      }

      else if (command == "usemtl")
      {
        std::string mtl = split(line, ' ', 1);
        filePackage.materialGroups[indexOffset] = mtl;
      }

      else if (command == "s")
      {
          std::string smooth = split(line, ' ', 1);
          if (smooth == "off")
          {
            filePackage.smoothGroups[indexOffset] = 0;
          }
          else
          {
            filePackage.smoothGroups[indexOffset] = std::stoi(smooth);
          }
      }

      else if (command == "o")
      {
        filePackage.objects[indexOffset] = split(line, ' ', 1);
      }

      else if (command == "g")
      {
        filePackage.objectGroups[indexOffset] = split(line, ' ', 1);
      }

      else if (command == "v")
      {
        float x = std::stof(split(line, ' ', 1));
        float y = std::stof(split(line, ' ', 2));
        float z = std::stof(split(line, ' ', 3));
        float w = 1.0f;
        if (tokenAmount == 4) {w = std::stof(split(line, ' ', 4));}
        filePackage.v.push_back(glm::vec4(x,y,z,w));
      }

      else if (command == "vt")
      {
        float u = std::stof(split(line, ' ', 1));
        float v = std::stof(split(line, ' ', 2));
        float w = 0.0f;
        if (tokenAmount == 3) {w = std::stof(split(line, ' ', 3));}
        filePackage.vt.push_back(glm::vec3(u, v, w));
      }

      else if (command == "vn")
      {
        float x = std::stof(split(line, ' ', 1));
        float y = std::stof(split(line, ' ', 2));
        float z = std::stof(split(line, ' ', 3));
        filePackage.vn.push_back(glm::vec3(x,y,z));
      }

      else if (command == "p")
      {
        int verticesInPoint = 1;
        std::string token = split(line, ' ', 1);
        int subTokenAmount = std::count(token.begin(), token.end(), '/') + 1;
        int v = std::stoi(split(token, '/', 0));
        int t = noData;
        int n = noData;
        int w = verticesInPoint;
        if (subTokenAmount == 2)
        {
          n = std::stoi(split(token, ' ', 1));
        }
        else if (subTokenAmount == 3)
        {
          std::string tex = split(token, '/', 1);
          if (tex != "") {t = std::stoi(tex);}
          n = std::stoi(split(token, '/', 2));
        }
        filePackage.f.push_back(glm::ivec4(v,t,n,w));
        indexOffset++;
      }

      else if (command == "l")
      {
        int verticesInLine = 2;
        for (int vert = 1; vert <= verticesInLine; vert++)
        {
          std::string token = split(line, ' ', vert);
          int subTokenAmount = std::count(token.begin(), token.end(), '/') + 1;
          int v = std::stoi(split(token, '/', 0));
          int t = noData;
          int n = noData;
          int w = verticesInLine;
          if (subTokenAmount == 2)
          {
            n = std::stoi(split(token, ' ', 1));
          }
          else if (subTokenAmount == 3)
          {
            std::string tex = split(token, '/', 1);
            if (tex != "") {t = std::stoi(tex);}
            n = std::stoi(split(token, '/', 2));
          }
          filePackage.f.push_back(glm::ivec4(v,t,n,w));
          indexOffset++;
        }
      }

      else if (command == "f")
      {
        int verticesInFace = tokenAmount;
        if (verticesInFace == 4) {hasQuads = true;}
        for (int vertex = 1; vertex <= verticesInFace; vertex++)
        {
          std::string token = split(line, ' ', vertex);
          int subTokenAmount = std::count(token.begin(), token.end(), '/') + 1;
          int v = std::stoi(split(token, '/', 0));
          int t = noData;
          int n = noData;
          int w = verticesInFace;
          if (subTokenAmount == 2)
          {
            n = std::stoi(split(token, ' ', 1));
          }
          else if (subTokenAmount == 3)
          {
            std::string tex = split(token, '/', 1);
            if (tex != "") {t = std::stoi(tex);}
            n = std::stoi(split(token, '/', 2));
          }
          filePackage.f.push_back(glm::ivec4(v,t,n,w));
          indexOffset++;
        }
      }

      else
      {
        std::cout << "Warning: Unrecognized command '" << command <<
               "' in OBJ file '" << filename << "'." << std::endl;
      }
    }
  }
  else
  {
    std::cout << "File " << filename <<
    " failed to open for reading..." << std::endl;
  }
  objFile.close();

  size_t materialAmount = mtllib.size();
  for (int n = 0; n < materialAmount; n++)
  {
    std::string materialFilename = mtllib[n];
    materialReader.read(filepath, materialFilename);
    filePackage.materialFilePackages.push_back(materialReader.wrapFilePackage());
  }
  if (hasQuads)
  {
    std::cout << "Warning: This OBJ file contains QUAD faces." <<
    " These will not be rendered." << std::endl;
  }
  return filePackage;
}

ie::WavefrontObjectFilePackage ie::WavefrontObjectFileReader::wrapFilePackage(void)
{
  return filePackage;
}

//______________________________________________________________________________

//___|WAVEFRONT MTL FILE READER|________________________________________________

ie::WavefrontMaterialFileReader::WavefrontMaterialFileReader(void) {}
ie::WavefrontMaterialFileReader::WavefrontMaterialFileReader(std::string filepath,
                                                             std::string filename)
{
  read(filepath, filename);
}

bool ie::WavefrontMaterialFileReader::clear(void)
{
  filePackage.materials.clear();
}

ie::WavefrontMaterialFilePackage ie::WavefrontMaterialFileReader::read(std::string filepath,
                                                                       std::string filename)
{
  std::ifstream mtlFile;
  mtlFile.open((filepath + filename).c_str());
  if (mtlFile.is_open())
  {
    clear();
    int materialOffset = -1;
    std::string line;
    while (getline(mtlFile, line))
    {
      std::string command = split(line, ' ', 0);
      if (command == "#") {continue;} //Comment
      else if (command == "") {continue;} //Blank

      else if (command == "newmtl")
      {
        materialOffset++;
        std::string name = split(line, ' ', 1);
        ie::WavefrontMaterialPackage newMaterialPackage;
        filePackage.materials.push_back(newMaterialPackage);
        filePackage.materials[materialOffset].filename = filename;
        filePackage.materials[materialOffset].filepath = filepath;
        filePackage.materials[materialOffset].name = name;
      }

      else if (command == "Ns")
      {
        filePackage.materials[materialOffset].shininess = std::stof(split(line, ' ', 1));
      }

      else if (command == "Ka")
      {
        float r = std::stof(split(line, ' ', 1));
        float g = std::stof(split(line, ' ', 2));
        float b = std::stof(split(line, ' ', 3));
        filePackage.materials[materialOffset].ambient = glm::vec3(r,g,b);
      }

      else if (command == "Kd")
      {
        float r = std::stof(split(line, ' ', 1));
        float g = std::stof(split(line, ' ', 2));
        float b = std::stof(split(line, ' ', 3));
        filePackage.materials[materialOffset].diffuse = glm::vec3(r,g,b);
      }

      else if (command == "Ks")
      {
        float r = std::stof(split(line, ' ', 1));
        float g = std::stof(split(line, ' ', 2));
        float b = std::stof(split(line, ' ', 3));
        filePackage.materials[materialOffset].specular = glm::vec3(r,g,b);
      }

      else if (command == "Ke")
      {
        float r = std::stof(split(line, ' ', 1));
        float g = std::stof(split(line, ' ', 2));
        float b = std::stof(split(line, ' ', 3));
        filePackage.materials[materialOffset].emission = glm::vec3(r,g,b);
      }

      else if (command == "Ni")
      {
        filePackage.materials[materialOffset].opticalDensity = std::stof(split(line, ' ', 1));
      }

      else if (command == "d")
      {
        filePackage.materials[materialOffset].dissolve = std::stof(split(line, ' ', 1));
      }

      else if (command == "Tr")
      {
        float Tr = std::stof(split(line, ' ', 1));
        float d = (Tr - 1) * -1;
        filePackage.materials[materialOffset].dissolve = d;
      }

      else if (command == "illum")
      {
        filePackage.materials[materialOffset].illum = std::stoi(split(line, ' ', 1));
      }
      else if (command == "map_Kd")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::DIFFUSE_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else if (command == "map_bump")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::BUMP_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else if (command == "map_Ka")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::AMBIENT_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else if (command == "map_Ks")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::SPECULAR_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else if (command == "map_Ns")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::HIGHLIGHT_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else if (command == "map_d")
      {
        ie::TexturePackage tex;
        size_t start = line.find(" ") + 1;
        tex.filename = line.substr(start);
        tex.type = ie::TextureType::ALPHA_MAP;
        tex.mipmapped = true;
        tex.anisotropy = true;
        tex.repeating = true;
        filePackage.materials[materialOffset].texturePackages.push_back(tex);
      }

      else
      {
        std::cout << "Warning: Unrecognized command '" << command <<
               "' in MTL file '" << filename << "'." << std::endl;
      }

    }
  }
  else
  {
    std::cout << "File " << filename <<
    " failed to open for reading..." << std::endl;
  }
  mtlFile.close();
  return filePackage;
}

ie::WavefrontMaterialFilePackage ie::WavefrontMaterialFileReader::wrapFilePackage(void)
{
  return filePackage;
}

//______________________________________________________________________________


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.PersonaBar.Pages.Components.Prompt.Commands
{
    using Dnn.PersonaBar.Library.Prompt;
    using Dnn.PersonaBar.Library.Prompt.Attributes;
    using Dnn.PersonaBar.Library.Prompt.Models;
    using Dnn.PersonaBar.Pages.Components.Security;
    using DotNetNuke.Entities.Portals;
    using DotNetNuke.Entities.Tabs;
    using DotNetNuke.Entities.Users;

    [ConsoleCommand("goto", Constants.PagesCategory, "Prompt_Goto_Description")]

    public class Goto : ConsoleCommandBase
    {
        [FlagParameter("name", "Prompt_Goto_FlagName", "String")]

        private const string FlagName = "name";

        [FlagParameter("id", "Prompt_Goto_FlagId", "Integer")]

        private const string FlagId = "id";

        [FlagParameter("parentid", "Prompt_Goto_FlagParentId", "Integer")]

        private const string FlagParentId = "parentid";

        /// <inheritdoc/>
        public override string LocalResourceFile => Constants.LocalResourceFile;

        private int PageId { get; set; } = -1;

        private string PageName { get; set; }

        private int ParentId { get; set; } = -1;

        /// <inheritdoc/>
        public override void Init(string[] args, PortalSettings portalSettings, UserInfo userInfo, int activeTabId)
        {
            this.PageId = this.GetFlagValue(FlagId, "Page Id", -1, false, true);
            this.ParentId = this.GetFlagValue(FlagParentId, "Parent Id", -1);
            this.PageName = this.GetFlagValue(FlagName, "Page Name", string.Empty);

            if (this.PageId == -1 && string.IsNullOrEmpty(this.PageName))
            {
                this.AddMessage(this.LocalizeString("Prompt_ParameterRequired"));
            }
        }

        /// <inheritdoc/>
        public override ConsoleResultModel Run()
        {
            var tab = this.PageId > 0
                ? TabController.Instance.GetTab(this.PageId, this.PortalId)
                : (this.ParentId > 0
                    ? TabController.Instance.GetTabByName(this.PageName, this.PortalId, this.ParentId)
                    : TabController.Instance.GetTabByName(this.PageName, this.PortalId));

            if (tab == null)
            {
                return new ConsoleErrorResultModel(this.LocalizeString("Prompt_PageNotFound"));
            }

            if (!SecurityService.Instance.CanManagePage(this.PageId))
            {
                return new ConsoleErrorResultModel(this.LocalizeString("MethodPermissionDenied"));
            }

            return new ConsoleResultModel(tab.FullUrl) { MustReload = true };
        }
    }
}


text:
Tools in this directory were hacked together on OS X
for vmware fusion using Python 2.7.  They may not
function properly on other platforms or configurations.
Also, keep in mind these are simple tools to get
something working so they may not be the most 'correct'
thing in the world.