text:
Angular playground
==================

Playing around with architecture and components. Really, just making sure
sh.t scales.

Installation
------------

    $ git clone https://github.com/bdo-labs/agular-playground.git
    $ make -s serve

Background
----------

A decision was made to use Angular on new and upcoming projects at BDO.
Since I am to take ownership of the front-end code, I need to understand
the framework and architecture completely. That way, I can ensure that it
will scale without too much hick-ups on the way. Having worked with
web-sites/app for more than a decade, I've come to find some patterns that
works better than others. The most important lesson I think, has been
breaking things apart into small components. That will be the main goal of
this playground, creating small components that can be used anywhere
throughout the code without being cumbersome.

Resources
---------

  - [Cliff Meyers](http://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript)
  - [Joel Hooks](http://joelhooks.com/blog/2013/05/22/lessons-learned-kicking-off-an-angularjs-project/)
  - [Jason Dobry](https://coderwall.com/p/y0zkiw)

Thoughts about these resources
------------------------------

Their mostly about organizing code, and the gist of it is that the way the
Angular-team recommends you structure your app, will just get you so far.
Cliff Meyers refers to the structure as the "Sock drawer". The problem is
separation between code and functionality. The solution seems to be to
structure by functionality and keep logically connected parts close. I'll
take this concept quite far by making code require-able as modules through
the use of `commonjs` and concatenate css from within each component at
build. Doing so means we can create entirely separate applications, but use
the same components at will.

License
-------

> The MIT License (MIT)

> Copyright (c) 2014 BDO digital solutions

> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
> the Software, and to permit persons to whom the Software is furnished to do so,
> subject to the following conditions:

> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.

> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


text:
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;

namespace MobileDetect.Contracts
{
    /// <summary>
    /// The base feature detection rule.
    /// </summary>
    /// <remarks>This will not detect anything.</remarks>
    public abstract class BaseRules
    {
        private readonly string UserAgentHeaderName = "User-Agent";

        /// <summary>
        /// Get the user agent header value.
        /// </summary>
        public virtual string GetUserAgent(ICollection<KeyValuePair<string, StringValues>> requestHeaders)
        {
            if (requestHeaders == null)
                return null;

            foreach (var header in requestHeaders)
            {
                if (UserAgentHeaderName.Equals(header.Key, StringComparison.OrdinalIgnoreCase))
                {
                    return header.Value;
                }
            }
            return null;
        }

        /// <summary>
        /// Returns true if the collection contains a header which is a known mobile header.
        /// </summary>
        public virtual bool HasKnownMobileHeaders(ICollection<KeyValuePair<string, StringValues>> requestHeaders) => false;

        /// <summary>
        /// Returns true if the collection contains a header which is a known tablet header.
        /// </summary>
        public virtual bool HasKnownTabletHeaders(ICollection<KeyValuePair<string, StringValues>> requestHeaders) => false;

        /// <summary>
        /// Returns true if the collection contains a `user agent` string which is a known mobile value.
        /// </summary>
        public virtual bool HasKnownMobileUserAgent(string userAgent) => false;

        /// <summary>
        /// Returns true if the collection contains a `user agent` string which is a known tablet value.
        /// </summary>
        public virtual bool HasKnownTabletUserAgent(string userAgent) => false;
    }
}

redpajama_set_name: RedPajamaGithub


text:
package game.view;

import game.controller.input.SimpleKeyboard;
import game.entity.types.Level;
import game.entity.types.Player;
import game.view.gfx.Lerret;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * Vinduet som vises når dere spiller spillet. Det er her lerretet bor.
 * Hvis dere vil ha ting som skal vises til høyre
 * (til dømes tid som er igjen, eller om dere vil implementere items eller noe,
 * er dette stedet å gjøre det på.)
 *
 * To instanser anses å være like hviss de er samme instans, så equals og hashCode er ikke overkjørt.
 *
 * @author Haakon Løtveit (haakon.lotveit@student.uib.no)
 *
 */
public class GameWindow extends JFrame {
	/**
	 * autogennet
	 */
	private static final long serialVersionUID = 4499966461488101017L;
	private static final String TITLE = "Kjip's Challenge";
	private SimpleKeyboard keyboard;
	private Player player;
	private Lerret lerret;

	public GameWindow(SimpleKeyboard keyboard, Player player){
		super(TITLE);
		this.keyboard = keyboard;
		this.player = player;
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();

	}

	public void loadLevel(Level level){
		if(null == lerret){
			this.lerret = new Lerret(level, player, keyboard);
			this.add(lerret);
		}
		this.lerret.setLevel(level);
		this.setSize(0,0);
		this.pack();
		this.setVisible(true);
	}

	public boolean popupDeath(){
		Object[] options = {"Restart", "Exit"};
		int choice = JOptionPane.showOptionDialog(this, "You're dead.\nNow what do you do?", "Death and such",
				JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
				null, options, options[0]);

		return 0==choice;
	}

	/*
	 * TODO: Selv om disse popupene virker, burde en ha bedre tekst.
	 */
	public void popupVictory() {
		popupGeneric("Ferdig!", "Brett klart");
	}

	public void popupGameComplete() {
		popupGeneric("Spill rundet", "Ferdig!");
	}

	public void popupGeneric(String title, String message){
		JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
	}
}


text:
[![devDependency Status](https://david-dm.org/tmwagency/kickoff/dev-status.png)](https://david-dm.org/tmwagency/kickoff#info=devDependencies) [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/tmwagency/kickoff/trend.png)](https://bitdeli.com/free "Bitdeli Badge") [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/)

![](http://f.cl.ly/items/3d0o1O190m0U443I0B1I/Screen%20Shot%202013-10-07%20at%2022.05.42.png)

# Kickoff

Developed and maintained by [Ashley Nolan](https://github.com/dragongraphics) & [Zander Martineau](https://github.com/mrmartineau)

If you're using Kickoff we'd love to hear about it; please e-mail us at labs@tmw.co.uk

### Features

* Built in a mobile-first, responsive philosophy *(but can easily be used for fixed sites as well)*
* Sass mixins for many CSS3 features including gradients, REMs with fallbacks
* Starter content styles, including clean typography, lists, tables, etc
* Starter form element styles: stacked on small-screen to 2-column (if you choose) at the breakpoint of your choice
* Grunt used extensively to ease common development bottlenecks
 * Sass compilation using [grunt-contrib-sass](https://github.com/gruntjs/grunt-contrib-sass)
 * Concatenation and minification of JS files with and [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify)
 * Simple server using [grunt-contrib-connect](https://github.com/gruntjs/grunt-contrib-connect)

### Browser support
Simple: Internet Explorer 8+

## Demos and documentation
Please visit [tmwagency.github.io/kickoff/](http://tmwagency.github.io/kickoff/) all demos and documentation for Kickoff.

## Want to use Grunt?
* Install Node from [nodejs.org](http://nodejs.org/)
* Install Grunt CLI - `npm install -g grunt-cli`
* Install Sass globally - `sudo gem install sass --pre`. [Ruby](https://www.ruby-lang.org/en/) v2 is needed. Update using [rvm](http://rvm.io/), [brew](http://brew.sh) (if you use a Mac) or from [ruby-lang.org/en/downloads/](https://www.ruby-lang.org/en/downloads/) then install the packages below
* Navigate (`cd`) to your project directory and run `npm install` which will install all Grunt's dependencies
* Run `grunt watch` or `grunt serve` (if you want to create a simple local server) to watch for changes and compile Sass/Javascript

When using Grunt with Kickoff, source maps are created for both the Javascript and Sass. Javascript is compiled to the `/js/dist` and Sass is compiled to the '/css' folder.

## Using Git?
Kickoff's [.gitignore](https://github.com/tmwagency/kickoff/blob/master/.gitignore#L30) file ignores the `/dist` folder by default. You will want to uncomment this line if you are **not** compiling these on the server.

## Yeoman generator
There is also a Yeoman generator for Kickoff, visit [tmwagency.github.io/kickoff/docs/yeoman.html](http://tmwagency.github.io/kickoff/docs/yeoman.html) for more info.

## Contributing

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -m 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request


text:
"""
    Vector math utilities for Python
"""

from distutils.core import setup
from setuptools import find_packages

CLASSIFIERS = [
    'Development Status :: 4 - Beta',
    'Programming Language :: Python',
    'Topic :: Scientific/Engineering',
    'Topic :: Scientific/Engineering :: Mathematics',
    'Topic :: Scientific/Engineering :: Physics',
    'Operating System :: Microsoft :: Windows',
    'Operating System :: POSIX',
    'Operating System :: Unix',
    'Operating System :: MacOS',
    'Natural Language :: English',
]

with open('README.rst') as f:
    LONG_DESCRIPTION = ''.join(f.readlines())

setup(
    name='vectormath',
    version='0.2.2',
    packages=find_packages(),
    install_requires=[
        'numpy>=1.7',
    ],
    author='Seequent',
    author_email='it@seequent.com',
    description='vectormath: vector math utilities for Python',
    long_description=LONG_DESCRIPTION,
    keywords='linear algebra, vector, plane, math',
    url='https://github.com/seequent/vectormath',
    download_url='https://github.com/seequent/vectormath',
    classifiers=CLASSIFIERS,
    platforms=['Windows', 'Linux', 'Solaris', 'Mac OS-X', 'Unix'],
    license='MIT License',
    include_package_data=True,
    use_2to3=False,
)


text:
//  This example shows how to create a simple lexer recognizing a couple of
//  different tokens aimed at a simple language and how to use this lexer with
//  a grammar. It shows how to associate attributes to tokens and how to access the
//  token attributes from inside the grammar.
//
//  Additionally, this example demonstrates, how to define a token set usable
//  as the skip parser during parsing, allowing to define several tokens to be
//  ignored.
//
//  The main purpose of this example is to show how inheritance can be used to
//  overload parts of a base grammar and add token definitions to a base lexer.
//
//  Further, it shows how you can use the 'omit' attribute type specifier
//  for token definitions to force the token to have no attribute (expose an
//  unused attribute).
//
//  This example recognizes a very simple programming language having
//  assignment statements and if and while control structures. Look at the file
//  example5.input for an example.

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <fstream>
#include <string>

#include "example.hpp"

using namespace boost::spirit;
using boost::phoenix::val;

///////////////////////////////////////////////////////////////////////////////
//  Token definition base, defines all tokens for the base grammar below
///////////////////////////////////////////////////////////////////////////////
template <typename Lexer>
struct example5_base_tokens : lex::lexer<Lexer>
{
protected:
    // this lexer is supposed to be used as a base type only
    example5_base_tokens() {}

public:
    void init_token_definitions()
    {
        // define the tokens to match
        identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
        constant = "[0-9]+";
        if_ = "if";
        while_ = "while";

        // associate the tokens and the token set with the lexer
        this->self += lex::token_def<>('(') | ')' | '{' | '}' | '=' | ';' | constant;
        this->self += if_ | while_ | identifier;

        // define the whitespace to ignore (spaces, tabs, newlines and C-style
        // comments)
        this->self("WS")
            =   lex::token_def<>("[ \\t\\n]+")
            |   "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"
            ;
    }

    // these tokens have no attribute
    lex::token_def<lex::omit> if_, while_;

    // The following two tokens have an associated attribute type, 'identifier'
    // carries a string (the identifier name) and 'constant' carries the
    // matched integer value.
    //
    // Note: any token attribute type explicitly specified in a token_def<>
    //       declaration needs to be listed during token type definition as
    //       well (see the typedef for the token_type below).
    //
    // The conversion of the matched input to an instance of this type occurs
    // once (on first access), which makes token attributes as efficient as
    // possible. Moreover, token instances are constructed once by the lexer
    // library. From this point on tokens are passed by reference only,
    // avoiding them being copied around.
    lex::token_def<std::string> identifier;
    lex::token_def<unsigned int> constant;
};

///////////////////////////////////////////////////////////////////////////////
//  Grammar definition base, defines a basic language
///////////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Lexer>
struct example5_base_grammar
  : qi::grammar<Iterator, qi::in_state_skipper<Lexer> >
{
    template <typename TokenDef>
    example5_base_grammar(TokenDef const& tok)
      : example5_base_grammar::base_type(program)
    {
        using boost::spirit::_val;

        program
            =  +block
            ;

        block
            =   '{' >> *statement >> '}'
            ;

        statement
            =   assignment
            |   if_stmt
            |   while_stmt
            ;

        assignment
            =   (tok.identifier >> '=' >> expression >> ';')
                [
                    std::cout << val("assignment statement to: ") << _1 << "\n"
                ]
            ;

        if_stmt
            =   (tok.if_ >> '(' >> expression >> ')' >> block)
                [
                    std::cout << val("if expression: ") << _1 << "\n"
                ]
            ;

        while_stmt
            =   (tok.while_ >> '(' >> expression >> ')' >> block)
                [
                    std::cout << val("while expression: ") << _1 << "\n"
                ]
            ;

        //  since expression has a variant return type accommodating for
        //  std::string and unsigned integer, both possible values may be
        //  returned to the calling rule
        expression
            =   tok.identifier [ _val = _1 ]
            |   tok.constant   [ _val = _1 ]
            ;
    }

    typedef qi::in_state_skipper<Lexer> skipper_type;

    qi::rule<Iterator, skipper_type> program, block, statement;
    qi::rule<Iterator, skipper_type> assignment, if_stmt;
    qi::rule<Iterator, skipper_type> while_stmt;

    //  the expression is the only rule having a return value
    typedef boost::variant<unsigned int, std::string> expression_type;
    qi::rule<Iterator, expression_type(), skipper_type>  expression;
};

///////////////////////////////////////////////////////////////////////////////
//  Token definition for derived lexer, defines additional tokens
///////////////////////////////////////////////////////////////////////////////
template <typename Lexer>
struct example5_tokens : example5_base_tokens<Lexer>
{
    typedef example5_base_tokens<Lexer> base_type;

    example5_tokens()
    {
        // define the additional token to match
        else_ = "else";

        // associate the new token with the lexer, note we add 'else' before
        // anything else to add it to the token set before the identifier
        // token, otherwise "else" would be matched as an identifier
        this->self = else_;

        // now add the token definitions from the base class
        this->base_type::init_token_definitions();
    }

    // this token has no attribute
    lex::token_def<lex::omit> else_;
};

///////////////////////////////////////////////////////////////////////////////
//  Derived grammar definition, defines a language extension
///////////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Lexer>
struct example5_grammar : example5_base_grammar<Iterator, Lexer>
{
    template <typename TokenDef>
    example5_grammar(TokenDef const& tok)
      : example5_base_grammar<Iterator, Lexer>(tok)
    {
        // we alter the if_stmt only
        this->if_stmt
            =   this->if_stmt.copy() >> -(tok.else_ >> this->block)
            ;
    }
};

///////////////////////////////////////////////////////////////////////////////
int main()
{
    // iterator type used to expose the underlying input stream
    typedef std::string::iterator base_iterator_type;

    // This is the lexer token type to use. The second template parameter lists
    // all attribute types used for token_def's during token definition (see
    // example5_base_tokens<> above). Here we use the predefined lexertl token
    // type, but any compatible token type may be used instead.
    //
    // If you don't list any token attribute types in the following declaration
    // (or just use the default token type: lexertl_token<base_iterator_type>)
    // it will compile and work just fine, just a bit less efficient. This is
    // because the token attribute will be generated from the matched input
    // sequence every time it is requested. But as soon as you specify at
    // least one token attribute type you'll have to list all attribute types
    // used for token_def<> declarations in the token definition class above,
    // otherwise compilation errors will occur.
    typedef lex::lexertl::token<
        base_iterator_type, boost::mpl::vector<unsigned int, std::string>
    > token_type;

    // Here we use the lexertl based lexer engine.
    typedef lex::lexertl::lexer<token_type> lexer_type;

    // This is the token definition type (derived from the given lexer type).
    typedef example5_tokens<lexer_type> example5_tokens;

    // this is the iterator type exposed by the lexer
    typedef example5_tokens::iterator_type iterator_type;

    // this is the type of the grammar to parse
    typedef example5_grammar<iterator_type, example5_tokens::lexer_def> example5_grammar;

    // now we use the types defined above to create the lexer and grammar
    // object instances needed to invoke the parsing process
    example5_tokens tokens;                         // Our lexer
    example5_grammar calc(tokens);                  // Our parser

    std::string str (read_from_file("example5.input"));

    // At this point we generate the iterator pair used to expose the
    // tokenized input stream.
    std::string::iterator it = str.begin();
    iterator_type iter = tokens.begin(it, str.end());
    iterator_type end = tokens.end();

    // Parsing is done based on the the token stream, not the character
    // stream read from the input.
    // Note how we use the lexer defined above as the skip parser. It must
    // be explicitly wrapped inside a state directive, switching the lexer
    // state for the duration of skipping whitespace.
    std::string ws("WS");
    bool r = qi::phrase_parse(iter, end, calc, qi::in_state(ws)[tokens.self]);

    if (r && iter == end)
    {
        std::cout << "-------------------------\n";
        std::cout << "Parsing succeeded\n";
        std::cout << "-------------------------\n";
    }
    else
    {
        std::cout << "-------------------------\n";
        std::cout << "Parsing failed\n";
        std::cout << "-------------------------\n";
    }

    std::cout << "Bye... :-) \n\n";
    return 0;
}


text:
var bunyan = require('bunyan'),
	Hoek = require('hoek'),
	_ = require('lodash'),
	containsTags = require('./utils.js').containsTags,
	noop = function() {},
	reqSerializer = function(req) {
		var obj = {
			id: req.id,
			headers: req.headers,
			method: req.method,
			info: req.info,
			path: req.path,
			params: req.params,
			query: req.query
		};
		return obj;
	},
	defaults = {
		tags: ['*'],
		ignoredTags: [],
		shouldLog: null,
		bunyan: {
			name: 'hapi-logger',
			serializers: {
				req: reqSerializer
			},
			src: false,
			level: 'debug'
		}
	};

module.exports.register = function (server, options, next) {

	var settings = Hoek.applyToDefaults(defaults, options || {}),
		logger = bunyan.createLogger(settings.bunyan),
		shouldLog = _.isFunction(settings.shouldLog) ? settings.shouldLog : noop,
		getMsgFromEvent = function(event) {
			var msg;
			if (_.isString(event.data)) {
				msg = event.data;
			}
			else if (_.isObject(event.data) && event.data.message) {
				msg = event.data.message;
				delete event.data.message;
			}
			return msg;
		},
		getDataFromEvent = function(event) {
			var data = _.isObject(event.data) ? event.data : {};
			data.tags = event.tags;
			if (event.request) {
				data.requestId = event.request;
			}
			if (event.server) {
				data.serverUri = event.server;
			}
			return data;
		},
		cacheKeyResolver = function(eventTags) {
			return _.sortBy(eventTags).join(',');
		},
		containsIncludedTags = _.memoize(containsTags.bind(null, settings.tags), cacheKeyResolver),
		containsIgnoredTags = _.memoize(containsTags.bind(null, settings.ignoredTags), cacheKeyResolver);

	server.on('log', function(event) {
		if (containsIgnoredTags(event.tags) || !containsIncludedTags(event.tags)) {
			return;
		}
		var msg = getMsgFromEvent(event) || 'Hapi Server Log',
			data = getDataFromEvent(event);
		if (!shouldLog(data)) {
			return;
		}
		logger.info(data, msg);
	});

	server.on('request', function(request, event) {
		if (containsIgnoredTags(event.tags) || !containsIncludedTags(event.tags)) {
			return;
		}
		var msg = getMsgFromEvent(event) || 'Hapi Server Request Log',
			data = getDataFromEvent(event);
		if (!shouldLog(data)) {
			return;
		}
		data.req = request;
		logger.info(data, msg);
	});

	server.on('request-internal', function(request, event) {
		if (containsIgnoredTags(event.tags) || !containsIncludedTags(event.tags)) {
			return;
		}
		var msg = getMsgFromEvent(event) || 'Hapi Server Request Internal Log',
			data = getDataFromEvent(event);
		if (!shouldLog(data)) {
			return;
		}
		data.req = request;
		logger.info(data, msg);
	});

	server.on('request-error', function(request, error) {
		if (containsIgnoredTags(['internal', 'error']) || !containsIncludedTags(['internal', 'error'])) {
			return;
		}
		var msg = error.message,
			data = {
				tags: ['internal', 'error'],
				req: request,
				stack: error.stack
			};
		if (!shouldLog(data)) {
			return;
		}
		logger.info(data, msg);
	});

	server.expose('logger', logger);

	next();
};

module.exports.register.attributes = {
	pkg: require('../package.json')
};


text:
package bt.peer;

import bt.net.Peer;

import java.util.Collection;

/**
 * A source of peers for a torrent
 *
 * @since 1.0
 */
public interface PeerSource {

    /**
     * Ask to update the list of peers (usually from an external source).
     * Implementations may choose to refuse to perform an update under certain conditions,
     * e.g. when insufficient time has passed since the last update.
     *
     * @return true if the list of peers has been updated; false otherwise
     * @since 1.0
     */
    boolean update();

    /**
     * Get the list of peers.
     * Implementations should return empty list before {@link #update} has been called for the first time.
     *
     * @return List of peers
     * @since 1.0
     */
    Collection<Peer> getPeers();
}


text:
var fs = require('fs'),
    path = require('path'),
    po2json = require('po2json'),
    walk = require('walk');

module.exports = function (options, callback) {

  this.filesByExtension = {};
  this.fileNames = null;

  if (options.directory)
    var walker = walk.walk(options.directory, { followLinks: false });

  var fileNames = [];

  var extensions = options.extensions.map(function(ext) {
    return ext.replace(/\./g, '\\.');
  }).join('|');
  var nameRegex = new RegExp('(' + extensions + ')$');
  var cwd = process.cwd() + path.sep;

  var that = this;
  walker.on('file', function(root, stats, next) {

    var fullFileName = path.join(root, stats.name);
    if (excludeFile(fullFileName, options.exclude)) {
      return next();
    }

    var fileName = fullFileName.replace(cwd, '');

    var extension = fileName.match(nameRegex);
    if (!extension || !extension[0]) return next();
    saveFileByExtension( that.filesByExtension, extension[0], fileName );
    fileNames.push(fileName);
    next();
  });

  walker.on('end', function() {
    this.fileNames = fileNames;
    callback(fileNames);
  });
}

function saveFileByExtension(filesByExtension, extension, fileName) {
  if (!filesByExtension[extension])
    filesByExtension[extension] = [];
  filesByExtension[extension].push(fileName);
}

function excludeFile (fileName, excludeDirs) {
  if(excludeDirs.length > 0) {
    var isExcludeDir = false;
    excludeDirs.forEach(function (dir) {
      if(fileName.indexOf(dir) != -1) {
        isExcludeDir = true;
        return false;
      };
    });
    if (isExcludeDir) {
      return true;
    }
  }
  return false;
}


text:
<bill session="110" type="s" number="2430" updated="2009-01-09T16:55:16-05:00">
	<status><introduced date="1196917200" datetime="2007-12-06"/></status>

	<introduced date="1196917200" datetime="2007-12-06"/>
	<titles>
		<title type="short" as="introduced">Maritime Emergency Prevention Act of 2007</title>
		<title type="official" as="introduced">A bill to prevent maritime emergencies, and for other purposes.</title>
	</titles>
	<sponsor id="300011"/>
	<cosponsors>
		<cosponsor id="300043" joined="2007-12-06"/>
	</cosponsors>
	<actions>
		<action date="1196917200" datetime="2007-12-06"><text>Read twice and referred to the Committee on Commerce, Science, and Transportation.</text></action>
	</actions>
	<committees>

	</committees>
	<relatedbills>

	</relatedbills>
	<subjects>

	</subjects>
	<amendments>

	</amendments>

	12/6/2007--Introduced.
Maritime Emergency Prevention Act of 2007 - Authorizes the Secretary of the department in which the Coast Guard is operating to command, using the Vessel Traffic Service (VTS), the pilot of a vessel to modify the speed or direction of a vessel in an emergency or hazardous conditions as determined by the local Coast Guard (CG) VTS director. Prohibits the filing of a civil action for damages against the Secretary or any officer in the exercise of their authority under this Act in any federal or state court. Requires a federally licensed pilot of a vessel to carry and use a laptop computer equipped with a navigation system in cases where state or local pilotage authorities determine that the use of such computer is practical and necessary.

</bill>


text:
package models;

import java.util.*;
import javax.persistence.*;

import play.db.ebean.*;
import play.data.format.*;
import play.data.validation.*;

import com.avaje.ebean.*;

@Entity
public class ArvoreAjuste extends Model {
   @Id
    public Long id;

    public Long num_arvore;
    public Long equacao_id;
    public Double qtd_biomassa_obs;
    public Double qtd_carbono_obs;
    public Double qtd_carbono_est;
    public Double qtd_volume_obs;
    public Double qtd_volume_est;
    public Double qtd_biomassa_est;

    @ManyToOne
    public Local local;

    @OneToMany(targetEntity = ArvoreAjusteVariavel.class, cascade = CascadeType.ALL)
    public List<ArvoreAjusteVariavel> arvore_ajuste_variavel= new ArrayList<ArvoreAjusteVariavel>();

    public static Model.Finder<Long,ArvoreAjuste> find = new Model.Finder<Long,ArvoreAjuste>(Long.class, ArvoreAjuste.class);

    public static List<ArvoreAjuste> findArvoreAjuste(Long idLocal, Long idEquacao) {
            return
                find.where()
                    .eq("local.id", idLocal)
                    .eq("equacao_id", idEquacao)
                    .findList();
        }

}


text:
package net.roboconf.dm.rest.services.internal;

import java.util.HashSet;
import java.util.Set;

import org.ops4j.pax.url.mvn.MavenResolver;

import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;

import net.roboconf.dm.management.Manager;
import net.roboconf.dm.rest.commons.security.AuthenticationManager;
import net.roboconf.dm.rest.services.cors.ResponseCorsFilter;
import net.roboconf.dm.rest.services.internal.resources.IApplicationResource;
import net.roboconf.dm.rest.services.internal.resources.IDebugResource;
import net.roboconf.dm.rest.services.internal.resources.IHistoryResource;
import net.roboconf.dm.rest.services.internal.resources.IPreferencesResource;
import net.roboconf.dm.rest.services.internal.resources.ITargetResource;
import net.roboconf.dm.rest.services.internal.resources.impl.ApplicationResource;
import net.roboconf.dm.rest.services.internal.resources.impl.AuthenticationResource;
import net.roboconf.dm.rest.services.internal.resources.impl.DebugResource;
import net.roboconf.dm.rest.services.internal.resources.impl.HistoryResource;
import net.roboconf.dm.rest.services.internal.resources.impl.ManagementResource;
import net.roboconf.dm.rest.services.internal.resources.impl.PreferencesResource;
import net.roboconf.dm.rest.services.internal.resources.impl.SchedulerResource;
import net.roboconf.dm.rest.services.internal.resources.impl.TargetResource;
import net.roboconf.dm.scheduler.IScheduler;

/**
 * @author Vincent Zurczak - Linagora
 */
public class RestApplication extends DefaultResourceConfig {

	private final IApplicationResource applicationResource;
	private final IDebugResource debugResource;
	private final ITargetResource targetResource;
	private final IPreferencesResource preferencesResource;
	private final IHistoryResource historyResource;

	private final ManagementResource managementResource;
	private final SchedulerResource schedulerResource;
	private final AuthenticationResource authenticationResource;

	/**
	 * Constructor.
	 * @param manager
	 */
	public RestApplication( Manager manager ) {
		super();

		this.applicationResource = new ApplicationResource( manager );
		this.managementResource = new ManagementResource( manager );
		this.debugResource = new DebugResource( manager );
		this.targetResource = new TargetResource( manager );
		this.preferencesResource = new PreferencesResource( manager );
		this.schedulerResource = new SchedulerResource( manager );
		this.authenticationResource = new AuthenticationResource( manager );
		this.historyResource = new HistoryResource( manager );

		getFeatures().put( "com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE );
		getFeatures().put( ResourceConfig.FEATURE_DISABLE_WADL, Boolean.TRUE );
	}

	@Override
	public Set<Class<?>> getClasses() {

		Set<Class<?>> result = new HashSet<> ();
		result.add( net.roboconf.dm.rest.commons.json.ObjectMapperProvider.class );
		result.add( com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.class );

		return result;
	}

	/**
	 * @return a non-null set with all the resource classes
	 */
	public static Set<Class<?>> getResourceClasses() {

		Set<Class<?>> result = new HashSet<> ();
		result.add( ApplicationResource.class );
		result.add( ManagementResource.class );
		result.add( DebugResource.class );
		result.add( TargetResource.class );
		result.add( PreferencesResource.class );
		result.add( SchedulerResource.class );
		result.add( AuthenticationResource.class );
		result.add( HistoryResource.class );

		return result;
	}

	@Override
	public Set<Object> getSingletons() {

		HashSet<Object> set = new HashSet<> ();
		set.add( this.applicationResource );
		set.add( this.managementResource );
		set.add( this.debugResource );
		set.add( this.targetResource );
		set.add( this.preferencesResource );
		set.add( this.schedulerResource );
		set.add( this.authenticationResource );
		set.add( this.historyResource );

		return set;
	}

	/**
	 * Sets the scheduler.
	 * @param scheduler the scheduler (can be null)
	 */
	public void setScheduler( IScheduler scheduler ) {
		this.schedulerResource.setScheduler( scheduler );
	}

	/**
	 * Sets the Maven resolver.
	 * @param mavenResolver the Maven resolver (can be null)
	 */
	public void setMavenResolver( MavenResolver mavenResolver ) {
		this.managementResource.setMavenResolver( mavenResolver );
	}

	/**
	 * Sets the authentication manager.
	 * @param authenticationMngr the authentication manager (can be null)
	 */
	public void setAuthenticationManager( AuthenticationManager authenticationMngr ) {
		this.authenticationResource.setAuthenticationManager( authenticationMngr );
	}

	/**
	 * Enables or disables CORS.
	 * @param enableCors true to enable it
	 */
	public void enableCors( boolean enableCors ) {

		if( enableCors )
			getProperties().put( ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, ResponseCorsFilter.class.getName());
		else
			getProperties().remove( ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS );
	}
}


text:
ExponentialVolume::ExponentialVolume(const Colorf &sig_a, const Colorf &sig_s, const Colorf &emit, float phase_asymmetry,
	const BBox &region, float a, float b, const Vector &up)
	: VaryingDensityVolume(sig_a, sig_s, emit, phase_asymmetry), a(a), b(b), up(up), region(region)
{}
BBox ExponentialVolume::bound() const {
	return region;
}
bool ExponentialVolume::intersect(const Ray &ray, std::array<float, 2> &t) const {
	return region.intersect(ray, &t[0], &t[1]);
}
float ExponentialVolume::density(const Point &p) const {
	if (!region.inside(p)){
		return 0;
	}
	float h = up.dot(p - region.min);
	return a * std::exp(-b * h);
}


text:
package ie.dit.giantbombapp.controller;

import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import java.io.IOException;
import java.util.List;

import ie.dit.giantbombapp.controller.api.ApiManager;
import ie.dit.giantbombapp.model.database.DatabaseManager;
import ie.dit.giantbombapp.model.pojos.Promo;

import ie.dit.giantbombapp.model.pojos.PromosContainer;
import ie.dit.giantbombapp.model.pojos.Review;
import ie.dit.giantbombapp.model.pojos.ReviewsContainer;
import ie.dit.giantbombapp.model.pojos.Search;
import ie.dit.giantbombapp.model.pojos.SearchContainer;
import retrofit2.Call;

/**
 * Author: Graham Byrne
 *
 * Created: 15/11/2016
 * Modified: 25/11/2016
 *
 * This is the primary controller for the activities. It links each activity to the
 * SQLiteDatabase, as well as giving them a way to query the API
 */

public class MainController
{
    private static final String TAG = "MainController";
    private int totalPromoResults;
    private int totalReviewResults;
    private final ApiManager mApi = new ApiManager();
    private final DatabaseManager db;
    private final String apiKey, format, sort;
    private final ConnectivityManager connManager;
    private NetworkInfo networkInfo;
    private final int initialLimit;

    /**
     * Main constructor for MainController
     * @param ctx: Context, needed for creating the database
     * @param apiKey: API Key to use to verify each API call
     * @param format: Format by which to retrieve each API call
     * @param sort: The sorting type to use when querying the Reviews resource
     */
    public MainController(Context ctx, String apiKey, String format, String sort)
    {
        this.apiKey = apiKey;
        this.format = format;
        this.sort = sort;
        db = new DatabaseManager(ctx);
        openDatabase();
        initialLimit = 10;
        connManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    public void closeDatabase()
    {
        db.close();
    }

    public void openDatabase()
    {
        db.open();
    }

    /**
     * Fetch a single review from the database using a given Game Id
     * **/
    public Cursor fetchReview(int id)
    {
        return db.getReviewByGameId(id);
    }

    /**
     * Fetch every review in the database
     * **/
    public Cursor fetchAllReviews()
    {
        return db.getAllReviews();
    }

    /**
     * If the network is available and connected, this method gets the initial
     * number of Review objects given an initial limit, and enters each Review into
     * the local SQLLiteDatabase.
     *
     * It will also wipe the database each time it is called. This is to reduce the
     * amount of space the app takes up on the phone, as it is called each time the
     * app is launched.
     *
     * It uses a synchronised Retrofit call, so this method needs to be run off the
     * main UI thread
     */
    public void getInitialReviewData()
    {
        networkInfo = connManager.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            db.wipeReviews();
            Call<ReviewsContainer> call = mApi.getApi().getInitialReviews(apiKey, format, sort, initialLimit);
            ReviewsContainer container = null;
            try
            {
                container = call.execute().body();
            }
            catch (IOException e)
            {
                Log.d(TAG, "IOException when attempting to execute API call");
            }

            if(container != null)
            {
                List<Review> results = container.getResults();
                totalReviewResults = container.getNumberOfTotalResults();
                for (Review result : results)
                {

                    long dbInsert = db.insertReview(result);

                    if (dbInsert < 0)
                    {
                        Log.d(TAG, "There was an error when inserting the promo data into the database");
                    }
                }
                Log.d(TAG, "Entered initial Review data to database");
            }
        }
    }

    /**
     * This method is identical to the GetInitialReviews() method, except it returns each Review found
     * after a given offset, and within the limit specified.
     *
     * @param limit: Number of review items to retrieve
     * @param offset: Offset from which to search the API
     */
    public void getMoreReviewData(int limit, int offset)
    {
        networkInfo = connManager.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            Call<ReviewsContainer> call = mApi.getApi().getMoreReviews(apiKey, format, sort, limit, offset);
            ReviewsContainer container = null;
            try
            {
                container = call.execute().body();
            }
            catch (IOException e)
            {
                Log.d(TAG, "IOException when attempting to execute API call");
            }

            if(container != null)
            {
                List<Review> results = container.getResults();

                for (Review result : results)
                {

                    long dbInsert = db.insertReview(result);

                    if (dbInsert < 0)
                    {
                        Log.d(TAG, "There was an error when inserting the promo data into the database");
                    }
                }

                Log.d(TAG, "Extra Review data entered to database");
            }
        }
    }

    public int getTotalReviewResults()
    {
        return totalReviewResults;
    }

    /**
     * See fetchReview()
     */
    public Cursor fetchPromo(int id)
    {
        return db.getPromoByPromoId(id);
    }

    /**
     * See fetchAllReviews()
     */
    public Cursor fetchAllPromos()
    {
        return db.getAllPromos();
    }

    /**
     * See getInitialReviewData()
     */
    public void getInitialPromoData()
    {
        networkInfo = connManager.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            db.wipePromos();
            Call<PromosContainer> call = mApi.getApi().getInitialPromos(apiKey, format, initialLimit);
            PromosContainer container = null;
            try
            {
                container = call.execute().body();
            } catch (IOException e)
            {
                Log.d(TAG, "IOException when attempting to execute API call");
            }

            if(container != null)
            {
                totalPromoResults = container.getNumberOfTotalResults();

                List<Promo> results = container.getResults();

                for (Promo result : results)
                {

                    long dbInsert = db.insertPromo(result);

                    if (dbInsert < 0)
                    {
                        Log.d(TAG, "There was an error when inserting the promo data into the database");
                    }
                }
                Log.d(TAG, "Initial Promo data entered to database");
            }
        }
    }

    /**
     * See getMoreReviewData()
     */
    public void getMorePromoData(int limit, int offset)
    {
        networkInfo = connManager.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            Call<PromosContainer> call = mApi.getApi().getMorePromos(apiKey, format, limit, offset);
            PromosContainer container = null;
            try
            {
                container = call.execute().body();
            } catch (IOException e)
            {
                Log.d(TAG, "IOException when attempting to execute API call");
            }

            if(container != null)
            {
                List<Promo> results = container.getResults();

                for (Promo result : results)
                {

                    long dbInsert = db.insertPromo(result);

                    if (dbInsert < 0)
                    {
                        Log.d(TAG, "There was an error when inserting the promo data into the database");
                    }
                }
                Log.d(TAG, "Extra Promo data added to database");
            }
        }
    }

    public int getTotalPromoResults()
    {
        return totalPromoResults;
    }

    /**
     * This method is slightly different from the Review and Promo methods in that
     * it returns a list of Search objects instead of a Cursor. I think it would be
     * overkill to create a database table to hold every search result found for the
     * given query and resource
     *
     * @param query: The query for which to search
     * @param resource: The resource within which to search for the given query above
     *
     * @return: A list of Search objects
     */
    public List<Search> searchForData(String query, String resource)
    {
        networkInfo = connManager.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            query = "name:" + query;
            resource = resource.toLowerCase();
            resource = resource.replace(" ", "_");
            Call<SearchContainer> call = mApi.getApi().searchResource(resource, apiKey, format, query);
            SearchContainer container;
            try
            {
                container = call.execute().body();
            } catch (IOException e)
            {
                return null;
            }

            if(container != null)
            {
                return container.getResults();
            }
        }

        return null;

    }
}


text:
package com.intellij.plugins.haxe.lang.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugins.haxe.ide.HaxeLookupElement;
import com.intellij.plugins.haxe.ide.refactoring.move.HaxeFileMoveHandler;
import com.intellij.plugins.haxe.lang.lexer.HaxeTokenTypes;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.metadata.psi.HaxeMeta;
import com.intellij.plugins.haxe.metadata.util.HaxeMetadataUtils;
import com.intellij.plugins.haxe.model.*;
import com.intellij.plugins.haxe.model.type.*;
import com.intellij.plugins.haxe.util.*;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.JavaSourceUtil;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.stream.Collectors;

import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty;

abstract public class HaxeReferenceImpl extends HaxeExpressionImpl implements HaxeReference {

  public static final HaxeDebugLogger LOG = HaxeDebugLogger.getLogger();
  public static final String DOT = ".";
  private static final Key<HaxeGenericSpecialization> SPECIALIZATION_KEY = new Key<>("HAXE_SPECIALIZATION_KEY");

  //static {
  //  LOG.setLevel(Level.TRACE);
  //}  // Pull this out after debugging.

  public HaxeReferenceImpl(ASTNode node) {
    super(node);
  }

  @Override
  public PsiElement getElement() {
    return this;
  }

  @Override
  public PsiReference getReference() {
    return this;
  }

  @Override
  public TextRange getRangeInElement() {
    PsiElement nameElement = getReferenceNameElement();
    if (nameElement != null) {
      int startOffset = nameElement.getStartOffsetInParent();
      return new TextRange(startOffset, startOffset + nameElement.getTextLength());
    }

    PsiElement dot = getLastChild();
    if (DOT.equals(dot.getText())) {
      int index = dot.getStartOffsetInParent() + dot.getTextLength();
      return new TextRange(index, index);
    }

    return new TextRange(0, getTextLength());
  }

  @NotNull
  @Override
  public String getCanonicalText() {
    return getText();
  }

  @Override
  public int getTextOffset() {
    PsiElement nameElement = getReferenceNameElement();
    return nameElement != null ? nameElement.getTextOffset() : super.getTextOffset();
  }

  @Nullable
  public HaxeGenericSpecialization getSpecialization() {
    // CallExpressions need to resolve their child, rather than themselves.
    HaxeExpression expression = this;
    if (this instanceof HaxeCallExpression) {
      expression = ((HaxeCallExpression)this).getExpression();
    } else if (this instanceof HaxeNewExpression) {
      HaxeNewExpression newExpression = (HaxeNewExpression)this;
      PsiElement resolved = newExpression.getType().getReferenceExpression().resolve();
      HaxeClass haxeClass;
      if (resolved instanceof HaxeClass) {
        haxeClass = (HaxeClass) resolved;
      } else {
        SpecificHaxeClassReference typeReference = SpecificTypeReference.getUnknown(newExpression);
        haxeClass = null != typeReference ? typeReference.getHaxeClass() : null;
      }
      final HaxeClassResolveResult result = HaxeClassResolveResult.create(haxeClass);
      result.specializeByParameters(newExpression.getType().getTypeParam());
      return result.getSpecialization();
    }

    // The specialization for a reference comes from either the type of the left-hand side of the
    // expression, or failing that, from the class in which the reference appears, which is
    // exactly what tryGetLeftResolveResult() gives us.
    final HaxeClassResolveResult result = tryGetLeftResolveResult(expression);
    return result != HaxeClassResolveResult.EMPTY ? result.getSpecialization() : null;
  }

  @Override
  public boolean isSoft() {
    return false;
  }

  private List<? extends PsiElement> resolveNamesToParents(List<? extends PsiElement> nameList) {
    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("namelist: " + nameList.toString()));
    if (nameList == null || nameList.isEmpty()) {
      return Collections.emptyList();
    }

    List<PsiElement> result = new ArrayList<>();
    for (PsiElement element : nameList) {
      PsiElement elementToAdd = element;
      if (element instanceof HaxeComponentName) {
        PsiElement parent = element.getParent();
        if (null != parent && parent.isValid()) {
          // Don't look for package parents. It turns 'com' into 'com.xx'.
          // XXX: May need to walk the tree until we get to the PACKAGE_STATEMENT
          // element;
          if (!(parent instanceof PsiPackage)) {
            elementToAdd = parent;
          }
        }
      }
      result.add(elementToAdd);
    }
    return result;
  }

  @Override
  public PsiElement resolve() {
    return resolve(true);
  }

  public boolean resolveIsStaticExtension() {
    // @TODO: DIRTY HACK! to avoid rewriting all the code!
    HaxeResolver.INSTANCE.resolve(this, true);
    return null != HaxeResolver.isExtension ? HaxeResolver.isExtension.get() : false;
  }

  @NotNull
  @Override
  public JavaResolveResult advancedResolve(boolean incompleteCode) {
    final PsiElement resolved = resolve(incompleteCode);
    // TODO: Determine if we are using the right substitutor.
    // ?? XXX: Is the internal element here supposed to be a PsiClass sub-class ??
    return null != resolved ? new CandidateInfo(resolved, EmptySubstitutor.getInstance()) : JavaResolveResult.EMPTY;
  }

  @NotNull
  private JavaResolveResult[] multiResolve(boolean incompleteCode, boolean resolveToParents) {
    //
    // Resolving through this.resolve, or through the ResolveCache.resolve,
    // resolves to the *name* of the component.  That's what is cached, that's
    // what is returned.  For the Java processing code, the various reference types
    // are sub-classed, along with the base reference being aware of the type of the
    // entity.  Still, the base reference (PsiJavaReference) resolves to the
    // COMPONENT_NAME element, NOT the element type.  The various sub-classes
    // of PsiJavaReference (and PsiJavaCodeReferenceElement) return the actual
    // element type.  For example, you have to have to use PsiClassType.resolve
    // to get back a PsiClassType.
    //
    // For the Haxe code, we don't have a large number of reference sub-classes,
    // so we have to figure out what the expected parent type is and return that.
    // Luckily, most references have a COMPONENT_NAME element located immediately
    // below the parent in the PSI tree.  Therefore, when requested, we're going
    // to return the parent type.
    //
    // The root of the problem appears to be that the Java language processing
    // always expected the COMPONENT_NAME field.  However, the Haxe processing
    // (plugin) code was written to expect the type *containing* the
    // COMPONENT_NAME element (e.g. the named element not the name of the element).
    // Therefore, we now have an adapter, and have to tweak some things to make them
    // compatible.  Perhaps the proper answer is to make all of the plug-in code
    // expect the COMPONENT_NAME field, to be consistent, and then we won't need
    // the resolveToParents logic (here, at least).
    //

    List<? extends PsiElement> cachedNames = doResolve(this, incompleteCode);

    // CandidateInfo does some extra resolution work when checking validity, so
    // the results have to be turned into a CandidateInfoArray, and not just passed
    // around as the list that HaxeResolver returns.
    return toCandidateInfoArray(resolveToParents ? resolveNamesToParents(cachedNames) : cachedNames);
  }

  protected List<? extends PsiElement> doResolve(@NotNull HaxeReference reference, boolean incompleteCode) {
    return (HaxeResolver.INSTANCE).resolve(reference, incompleteCode);
  }

  /**
   * Resolve a reference, returning the COMPONENT_NAME field of the found
   * PsiElement.
   *
   * @return the component name of the found element, or null if not (or
   *   more than one) found.
   */
  @Nullable
  public PsiElement resolveToComponentName() {
    final ResolveResult[] resolveResults = multiResolve(true, false);
    final PsiElement result = resolveResults.length == 0 ||
                              resolveResults.length > 1 ||
                              !resolveResults[0].isValidResult() ? null : resolveResults[0].getElement();

    if (result != null && result instanceof HaxeNamedComponent) {
      return ((HaxeNamedComponent)result).getComponentName();
    }

    return result;
  }

  /**
   * Resolve a reference, returning a list of possible candidates.
   *
   * @param incompleteCode Whether to treat the code as a fragment or not.
   *                       Usually, code is considered incomplete.
   * @return a (possibly empty) list of candidates that this reference matches.
   */
  @NotNull
  @Override
  public JavaResolveResult[] multiResolve(boolean incompleteCode) {
    return multiResolve(incompleteCode, true);
  }

  /**
   * Resolve this reference to a PsiElement -- *NOT* it's name.
   *
   * @param incompleteCode Whether to treat the code as a fragment or not.
   *                       Usually, code is considered incomplete.
   * @return the element this reference refers to, or null if none (or more
   *   than one) is found.
   */
  @Nullable
  public PsiElement resolve(boolean incompleteCode) {
    if (LOG.isTraceEnabled()) LOG.trace(traceMsg(null));
    final ResolveResult[] resolveResults = multiResolve(incompleteCode);

    PsiElement resolved = resolveResults.length == 0 ||
                          resolveResults.length > 1 ||
                          !resolveResults[0].isValidResult() ? null : resolveResults[0].getElement();
    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("Resolved to " + (resolved != null ? resolved.toString() : "<null>")));
    return resolved;
  }

  @NotNull
  @Override
  public HaxeClassResolveResult resolveHaxeClass() {
    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("Begin resolving Haxe class:" + this.getText()));
    HaxeClassResolveResult result = resolveHaxeClassInternal();
    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("Finished resolving Haxe class " + this.getText() + " as " + result.debugDump()));
    return result;
  }

  /** Replacement for instanceof that has better logging and is easier to step over :) */
  @Contract("null->false")
  private boolean isType(Class clazz) {
    if (clazz.isInstance(this)) {
      if (LOG.isTraceEnabled()) LOG.traceAs(HaxeDebugUtil.getCallerStackFrame(), "Resolving " + this.getDebugName() + " as class type " + clazz.getName());
      return true;
    }
    if (LOG.isTraceEnabled()) LOG.traceAs(HaxeDebugUtil.getCallerStackFrame(), this.getDebugName() + " is not a " + clazz.getName());
    return false;
  }

  /** Replacement for instanceof that has better logging and is easier to step over :) */
  @Contract("null,_->false")
  private boolean isType(Object o, Class clazz) {
    if (clazz.isInstance(o)) {
      if (LOG.isTraceEnabled()) LOG.traceAs(HaxeDebugUtil.getCallerStackFrame(), "Resolving " + o + " as class type " + clazz.getName());
      return true;
    }
    if (LOG.isTraceEnabled()) LOG.traceAs(HaxeDebugUtil.getCallerStackFrame(), o + " is not a " + clazz.getName());
    return false;
  }

  @NotNull
  private HaxeClassResolveResult resolveHaxeClassInternal() {

    if (isType(HaxeThisExpression.class)) {
      HaxeClass clazz = PsiTreeUtil.getParentOfType(this, HaxeClass.class);
      // this has different semantics on abstracts
      if (clazz != null && clazz.getModel().isAbstract()) {
        HaxeTypeOrAnonymous type = clazz.getModel().getUnderlyingType();
        if (type != null) {
          return HaxeClassResolveResult.create(HaxeResolveUtil.tryResolveClassByQName(type));
        }
      }
      return HaxeClassResolveResult.create(clazz);
    }

    if (isType(HaxeSuperExpression.class)) {
      final HaxeClass haxeClass = PsiTreeUtil.getParentOfType(this, HaxeClass.class);
      assert haxeClass != null;
      if (haxeClass.getHaxeExtendsList().isEmpty()) {
        return HaxeClassResolveResult.create(null);
      }
      final HaxeExpression superExpression = haxeClass.getHaxeExtendsList().get(0).getReferenceExpression();
      final HaxeClassResolveResult superClassResolveResult = ((HaxeReference)superExpression).resolveHaxeClass();
      superClassResolveResult.specializeByParameters(haxeClass.getHaxeExtendsList().get(0).getTypeParam());
      return superClassResolveResult;
    }

    if (isType(HaxeStringLiteralExpression.class)) {
      return HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName("String", this));
    }

    if (isType(HaxeLiteralExpression.class)) {
      final PsiElement firstChild = getFirstChild();
      if (firstChild instanceof LeafPsiElement) {
        final LeafPsiElement child = (LeafPsiElement)getFirstChild();
        final IElementType childTokenType = child == null ? null : child.getElementType();
        return HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(getLiteralClassName(childTokenType), this));
      }
      // Else, it's a block statement and not a named literal.
      return HaxeClassResolveResult.create(null);
    }

    if (isType(HaxeMapLiteral.class)) {
      // Maps are created as specific types, using these rules (from Map.hx constructor documentation):
      //   This becomes a constructor call to one of the specialization types in
      //   the output. The rules for that are as follows:
      //
      //     1. if K is a `String`, `haxe.ds.StringMap` is used
      //     2. if K is an `Int`, `haxe.ds.IntMap` is used
      //     3. if K is an `EnumValue`, `haxe.ds.EnumValueMap` is used
      //     4. if K is any other class or structure, `haxe.ds.ObjectMap` is used
      //     5. if K is any other type, it causes a compile-time error
      //
      // Also, maps can be created via comprehensions, so if the expression is anything other than a FAT_ARROW,
      // we will have to get the type of the statement.
      HaxeMapLiteral haxeMapLiteral = (HaxeMapLiteral)this;
      HaxeExpressionEvaluatorContext context = new HaxeExpressionEvaluatorContext(this, null);
      HaxeExpressionEvaluator.evaluate(haxeMapLiteral, context, HaxeGenericResolverUtil.generateResolverFromScopeParents(this));

      SpecificHaxeClassReference mapClass = context.result.getClassType();
      return HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(mapClass.getClassName(), this));
    }

    if (isType(HaxeArrayLiteral.class)) {
      HaxeArrayLiteral haxeArrayLiteral = (HaxeArrayLiteral)this;
      HaxeExpressionList expressionList = haxeArrayLiteral.getExpressionList();
      boolean isString = false;
      boolean sameClass = false;
      boolean implementOrExtendSameClass = false;
      HaxeClass haxeClass = null;
      List<HaxeType> commonTypeList = new ArrayList<>();
      List<HaxeExpression> haxeExpressionList = expressionList != null ? expressionList.getExpressionList() : new ArrayList<>();
      if (!haxeExpressionList.isEmpty()) {
        isString = true;
        sameClass = true;

        for (HaxeExpression expression : haxeExpressionList) {
          if (!(expression instanceof HaxeStringLiteralExpression)) {
            isString = false;
          }

          if (sameClass || implementOrExtendSameClass) {
            HaxeReferenceExpression haxeReference = null;
            if (expression instanceof HaxeNewExpression || expression instanceof HaxeCallExpression) {
              haxeReference = PsiTreeUtil.findChildOfType(expression, HaxeReferenceExpression.class);
            }
            if (expression instanceof HaxeReferenceExpression) {
              haxeReference = (HaxeReferenceExpression)expression;
            }

            HaxeClass haxeClassResolveResultHaxeClass = null;
            if (haxeReference != null) {
              HaxeClassResolveResult haxeClassResolveResult = haxeReference.resolveHaxeClass();
              haxeClassResolveResultHaxeClass = haxeClassResolveResult.getHaxeClass();
              if (haxeClassResolveResultHaxeClass != null) {
                if (haxeClass == null) {
                  haxeClass = haxeClassResolveResultHaxeClass;
                  commonTypeList.addAll(haxeClass.getHaxeImplementsList());
                  commonTypeList.addAll(haxeClass.getHaxeExtendsList());
                }
              }
            }

            if (haxeClass != null && !haxeClass.equals(haxeClassResolveResultHaxeClass)) {
              List<HaxeType> haxeTypeList = new ArrayList<>();
              haxeTypeList.addAll(haxeClass.getHaxeImplementsList());
              haxeTypeList.addAll(haxeClass.getHaxeExtendsList());

              commonTypeList.retainAll(haxeTypeList);
              implementOrExtendSameClass = !commonTypeList.isEmpty();
            }

            if (haxeClass == null || !haxeClass.equals(haxeClassResolveResultHaxeClass)) {
              sameClass = false;
            }
          }
        }
      }
      HaxeClassResolveResult resolveResult =
        HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(getLiteralClassName(getTokenType()), this));

      HaxeClass resolveResultHaxeClass = resolveResult.getHaxeClass();

      HaxeGenericSpecialization specialization = resolveResult.getSpecialization();
      if (resolveResultHaxeClass != null &&
          specialization.get(resolveResultHaxeClass, "T") == null) {  // TODO: 'T' should not be hard-coded.
        if (isString) {
          specialization.put(resolveResultHaxeClass, "T", HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName("String", this)));
        } else if (sameClass) {
          specialization.put(resolveResultHaxeClass, "T",
                             HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(haxeClass.getQualifiedName(), this)));
        } else if (implementOrExtendSameClass) {
          HaxeReferenceExpression haxeReferenceExpression = commonTypeList.get(commonTypeList.size() - 1).getReferenceExpression();
          HaxeClassResolveResult resolveHaxeClass = haxeReferenceExpression.resolveHaxeClass();

          if (resolveHaxeClass != HaxeClassResolveResult.EMPTY) {
            HaxeClass resolveHaxeClassHaxeClass = resolveHaxeClass.getHaxeClass();

            if (resolveHaxeClassHaxeClass != null) {
              specialization.put(resolveResultHaxeClass, "T", HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(
                resolveHaxeClassHaxeClass.getQualifiedName(), this)));
            }
          }
        }
      }

      return resolveResult;
    } // end (this instanceof HaxeArrayLiteral)

    if (isType(HaxeNewExpression.class)) {
      final HaxeClassResolveResult result = HaxeClassResolveResult.create(HaxeResolveUtil.tryResolveClassByQName(
        ((HaxeNewExpression)this).getType()));
      result.specialize(this);
      return result;
    }

    if (isType(HaxeCallExpression.class)) {
      final HaxeExpression expression = ((HaxeCallExpression)this).getExpression();
      final HaxeClassResolveResult leftResult = tryGetLeftResolveResult(expression);
      if (expression instanceof HaxeReference) {
        final HaxeClassResolveResult result =
          HaxeResolveUtil.getHaxeClassResolveResult(((HaxeReference)expression).resolve(), leftResult.getSpecialization());
        result.specialize(this);
        return result;
      }
    }

    if (isType(HaxeArrayAccessExpression.class)) {
      // wrong generation. see HaxeCallExpression
      final HaxeReference reference = PsiTreeUtil.getChildOfType(this, HaxeReference.class);
      if (reference != null) {
        final HaxeClassResolveResult resolveResult = reference.resolveHaxeClass();
        final HaxeClass resolveResultHaxeClass = resolveResult.getHaxeClass();
        if (resolveResultHaxeClass == null) {
          return resolveResult;
        }
        // std Array
        if ("Array".equals(resolveResultHaxeClass.getQualifiedName())) {
          HaxeClassResolveResult arrayResolveResult = resolveResult.getSpecialization().get(resolveResultHaxeClass, "T");

          if (arrayResolveResult != null) {
            return arrayResolveResult;
          }
        }
        // @:arrayAccess methods, such as in Map or openfl.Vector
        HaxeNamedComponent arrayAccessGetter = resolveResultHaxeClass.findArrayAccessGetter(resolveResult.getGenericResolver());
        HaxeGenericResolver memberResolver = resolveResultHaxeClass.getMemberResolver(resolveResult.getGenericResolver());
        HaxeGenericSpecialization memberSpecialization = HaxeGenericSpecialization.fromGenericResolver(arrayAccessGetter, memberResolver);
        return HaxeResolveUtil.getHaxeClassResolveResult(arrayAccessGetter, memberSpecialization);
      }
    }

    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("Calling resolve()"));
    PsiElement resolve = resolve();
    if (isType(resolve, PsiPackage.class)) {
      // Packages don't ever resolve to classes. (And they don't have children!)
      return HaxeClassResolveResult.EMPTY;
    }
    if (isType(resolve, HaxeAnonymousTypeField.class)) {
      HaxeAnonymousTypeField field = (HaxeAnonymousTypeField)resolve;
      HaxeTypeTag typeTag = field.getTypeTag();
      if (null != typeTag && typeTag.getTypeOrAnonymous() != null) {
        HaxeTypeOrAnonymous typeOrAnonymous = typeTag.getTypeOrAnonymous();
        if (typeOrAnonymous != null) {
          if (typeOrAnonymous.getAnonymousType() != null) {
            return HaxeClassResolveResult.create(typeOrAnonymous.getAnonymousType(), getSpecialization());
          } else {
            HaxeType type = typeOrAnonymous.getType();
            if (type != null) {
              PsiElement resolvedType = type.getReferenceExpression().resolve();
              if(resolvedType instanceof HaxeGenericListPart) {
                final HaxeComponentName componentName = ((HaxeGenericListPart)resolvedType).getComponentName();
                final HaxeGenericSpecialization specialization = getSpecialization();
                if(specialization != null && componentName != null) {
                  String genericName = componentName.getText();
                  final HaxeClassResolveResult result = specialization.get(resolve, genericName);
                  if (result != null) {
                    return result;
                  }
                }
              }
              if (resolvedType instanceof HaxeClass) {
                return HaxeClassResolveResult.create((HaxeClass)resolvedType, getSpecialization());
              }
            }
          }
        }
      }
      return HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName("Dynamic", this));
    }

    if (isType(resolve, HaxeGenericListPart.class)) {
      final HaxeComponentName componentName = ((HaxeGenericListPart)resolve).getComponentName();
      if (componentName != null) {
        HaxeGenericSpecialization innerSpecialization =
          tryGetLeftResolveResult(this).getSpecialization();
        String genericName = componentName.getText();
        final HaxeClassResolveResult result = innerSpecialization.get(resolve, genericName);
        if (result != null) {
          return result;
        }
      }
    }

    if (isType(resolve, HaxeEnumValueDeclaration.class)) {
      final HaxeEnumDeclaration enumDeclaration = UsefulPsiTreeUtil.getParentOfType(resolve, HaxeEnumDeclaration.class);
      return HaxeClassResolveResult.create(enumDeclaration, getSpecialization());
    }

    if (isType(resolve, HaxeClass.class) || isType(resolve, HaxeFunctionLiteral.class)) {
      // Classes (particularly typedefs) that are already resolved should not be
      // re-resolved to their component parts.
      return HaxeClassResolveResult.create((HaxeClass)resolve, getSpecialization());
    }

    if (isType(resolve, HaxeMethod.class)) {
      // If the resolved element is a method, but the reference's parent is not a call expression, then
      // we want to return the method type, and not the method's return type.  (e.g. String->String->Void, rather than Void.)
      List<PsiElement> typeList = UsefulPsiTreeUtil.getPathToParentOfType(this, HaxeCallExpression.class);
      if (null == typeList || typeList.size() != 1) {

        HaxeGenericSpecialization specialization = getSpecialization();
        if (null == specialization) {
          specialization = new HaxeGenericSpecialization();
        }

        final HaxeClass fn = new HaxeSpecificFunction((HaxeMethod)resolve, specialization);
        return HaxeClassResolveResult.create(fn, specialization);
      }
    }

    if (resolve != null) {
      return HaxeResolveUtil.getHaxeClassResolveResult(resolve, getSpecialization());
    }

    if (LOG.isTraceEnabled()) LOG.trace(traceMsg("Trying class resolve by fully qualified name."));

    return HaxeClassResolveResult.create(HaxeResolveUtil.findClassByQName(getText(), this));
  }

  @Override
  public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
    PsiElement element = this;
    final HaxeIdentifier identifier = PsiTreeUtil.getChildOfType(element, HaxeIdentifier.class);
    final HaxeIdentifier identifierNew = HaxeElementGenerator.createIdentifierFromText(getProject(), newElementName);

    if (identifier != null && identifierNew != null) {
      element.getNode().replaceChild(identifier.getNode(), identifierNew.getNode());
    }
    return this;
  }

  @Override
  public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
    if (element instanceof HaxeFile) {
      bindToFile(element);
    } else if (element instanceof PsiPackage) {
      bindToPackage((PsiPackage)element);
    } else if (element instanceof PsiClass) {
      bindToClass((PsiClass)element);
    }
    return this;
  }

  private void bindToClass(PsiClass element) {
    String ref = getReferenceName();
    //The name was not changed. Are we moving a class to another package?
    if(element instanceof HaxeClassDeclaration && ref != null && ref.equals(element.getName())) {
      handleClassMovement(element);
    //rename
    } else {
      handleElementRename(element.getName());
    }
  }

  private void handleClassMovement(PsiClass element) {
    String thisFqn = getQualifiedName();
    //This reference is not a fully qualified name. Nothing to do.
    if(!thisFqn.contains(".")) {
      return;
    }
    String newFqn = ((HaxeClassDeclaration)element).getModel().haxeClass.getQualifiedName();
    updateFullyQualifiedReference(newFqn);
  }

  private void bindToPackage(PsiPackage element) {
    final HaxeImportStatement importStatement =
      HaxeElementGenerator.createImportStatementFromPath(getProject(), element.getQualifiedName());
    HaxeReferenceExpression referenceExpression = importStatement != null ? importStatement.getReferenceExpression() : null;
    if (referenceExpression == null) {
      LOG.error("ReferenceExpression generated by HaxeElementGenerator is null!");
    } else {
      replace(referenceExpression);
    }
  }

  private void bindToFile(PsiElement element) {
    final HaxeFileModel elementFileModel = HaxeFileModel.fromElement(element);
    final HaxeFileModel selfFileModel = HaxeFileModel.fromElement(this);
    String destinationPackage = element.getUserData(HaxeFileMoveHandler.destinationPackageKey);
    if (destinationPackage == null) {
      destinationPackage = "";
    }
    final String importPath = (destinationPackage.isEmpty() ? "" : destinationPackage + ".") +
                              elementFileModel.getName();

    if (resolve() == null) {
      final List<HaxeImportModel> imports = selfFileModel.getImportModels();
      final boolean isInImportStatement = getParent() instanceof HaxeImportStatement;
      final boolean isInQualifiedPath = getText().indexOf('.') != -1;
      final boolean inSamePackage = Objects.equals(selfFileModel.getPackageName(), elementFileModel.getPackageName());
      final boolean exposedByImports = imports.stream().anyMatch(
        model -> {
          return model.getExposedMembers().stream().anyMatch(item -> elementFileModel.getQualifiedInfo().equals(item.getQualifiedInfo()));
        });
      final boolean requiredToAddImport = !inSamePackage && (imports.isEmpty() || !exposedByImports);

      if (isInImportStatement) {
        if (inSamePackage || destinationPackage.isEmpty() || exposedByImports) {
          deleteImportStatement();
        } else {
          updateImportStatement(importPath);
        }
      } else if (isInQualifiedPath) {
        final String newName = destinationPackage.equals(selfFileModel.getPackageName()) ? elementFileModel.getName() : importPath;
        updateFullyQualifiedReference(newName);
      } else if (requiredToAddImport) {
        selfFileModel.addImport(importPath);
      }
    } else {
      final HaxeImportStatement importStatement = selfFileModel.getImportStatements().stream()
        .filter(statement -> statement.getReferenceExpression() != null && importPath.equals(statement.getReferenceExpression().getText()))
        .findFirst()
        .orElse(null);

      if (importStatement != null) {
        importStatement.delete();
      }
    }
  }

  private void updateFullyQualifiedReference(String newName) {
    HaxeReferenceExpression referenceExpression =
      HaxeElementGenerator.createReferenceExpressionFromText(getProject(), newName);
    if (referenceExpression == null) {
      LOG.error("ReferenceExpression generated by HaxeElementGenerator is null!");
    } else {
      replace(referenceExpression);
    }
  }

  private void updateImportStatement(String newImportPath) {
    HaxeImportStatement importStatement = (HaxeImportStatement)getParent();
    final HaxeImportStatement newImportStatement = HaxeElementGenerator.createImportStatementFromPath(getProject(), newImportPath);
    assert newImportStatement != null : "New import statement can't be null - HaxeElementGenerator failed";
    importStatement.replace(newImportStatement);
  }

  private void deleteImportStatement() {
    if (getParent() instanceof HaxeImportStatement) {
      try {
        getParent().delete();
      }
      catch (IncorrectOperationException ignored) {
      }
    }
  }

  @Override
  public boolean isReferenceTo(PsiElement element) {
    // Resolving is (relatively) expensive, so if we're going to ignore the answer anyway, then don't bother.
    if (!(element instanceof HaxeFile)) {
      final HaxeReference[] references = PsiTreeUtil.getChildrenOfType(this, HaxeReference.class);
      final boolean chain = references != null && references.length == 2;
      if (chain) return false;
    }
    final PsiElement resolve = element instanceof HaxeComponentName ? resolveToComponentName() : resolve();
    if (element instanceof HaxeFile && resolve instanceof HaxeClass) {
      return element == resolve.getContainingFile();
    }
    return resolve == element;
  }

  @NotNull
  @Override
  public Object[] getVariants() {
    final Set<HaxeComponentName> suggestedVariants = new HashSet<>();
    final Set<HaxeComponentName> suggestedVariantsExtensions = new HashSet<>();

    // if not first in chain
    // foo.bar.baz
    final HaxeReference leftReference = HaxeResolveUtil.getLeftReference(this);
    HaxeClassResolveResult result = null;
    HaxeClass haxeClass = null;
    String name = null;
    HaxeGenericResolver resolver = null;
    if (leftReference != null) {
      result = leftReference.resolveHaxeClass();
      if (result != HaxeClassResolveResult.EMPTY) {
        haxeClass = result.getHaxeClass();
        if (haxeClass != null) {
          name = haxeClass.getName();
        }
        resolver = result.getSpecialization().toGenericResolver(haxeClass);
      }
    }

    boolean isThis = leftReference instanceof HaxeThisExpression;
    if (leftReference != null && name != null &&
        HaxeResolveUtil.splitQName(leftReference.getText()).getSecond().equals(name)) {

      if (!isInUsingStatement() && !(isInImportStatement() && (haxeClass.isEnum() || haxeClass instanceof HaxeAbstractClassDeclaration))) {
        addClassStaticMembersVariants(suggestedVariants, haxeClass, !(isThis));
      }

      addChildClassVariants(suggestedVariants, haxeClass);
    } else if (leftReference != null && !result.isFunctionType()) {
      if (null == haxeClass) {
        // TODO: fix haxeClass by type inference. Use compiler code assist?!
      }
      if (haxeClass != null) {
        boolean isSuper = leftReference instanceof HaxeSuperExpression;
        PsiElement resolvedValue = leftReference.resolve();
        if (!isSuper && (resolvedValue instanceof HaxeClassDeclaration ||
                         resolvedValue instanceof HaxeAbstractClassDeclaration ||
                         resolvedValue instanceof HaxeInterfaceDeclaration ||
                         resolvedValue instanceof HaxeExternClassDeclaration)) {
          List<HaxeModel> models = HaxeProjectModel.fromElement(this).resolve(new FullyQualifiedInfo("", "Class", null, null));
          if (models != null && !models.isEmpty() && models.get(0) instanceof HaxeClassModel) {
            haxeClass = ((HaxeClassModel)models.get(0)).haxeClass;
          } else {
            haxeClass = null;
          }
        }

        addClassNonStaticMembersVariants(suggestedVariants, haxeClass, resolver,
                                         !(isThis || isSuper));
        addUsingVariants(suggestedVariants, suggestedVariantsExtensions, haxeClass, this);
      }
    } else {
      if (leftReference == null) {
        final boolean isElementInForwardMeta = HaxeAbstractForwardUtil.isElementInForwardMeta(this);
        if (isElementInForwardMeta) {
          final HaxeMeta meta = HaxeMetadataUtils.getEnclosingMeta(this);
          final PsiElement element = HaxeMetadataUtils.getAssociatedElement(meta);
          final HaxeClass clazz = element instanceof HaxeClass ? (HaxeClass)element : null;
          addAbstractUnderlyingClassVariants(suggestedVariants, clazz, resolver);
        } else {
          PsiTreeUtil.treeWalkUp(new ComponentNameScopeProcessor(suggestedVariants), this, null, new ResolveState());
          addClassVariants(suggestedVariants, PsiTreeUtil.getParentOfType(this, HaxeClass.class), false, resolver);
        }
      }
    }

    Object[] variants = HaxeLookupElement.convert(result, suggestedVariants, suggestedVariantsExtensions).toArray();
    PsiElement leftTarget = leftReference != null ? leftReference.resolve() : null;

    if (leftTarget instanceof PsiPackage) {
      return ArrayUtil.mergeArrays(variants, ((PsiPackage)leftTarget).getSubPackages());
    } else if (leftTarget instanceof HaxeFile) {
      return ArrayUtil.mergeArrays(variants, ((HaxeFile)leftTarget).getClasses());
    } else if (leftReference == null) {
      PsiPackage rootPackage = JavaPsiFacade.getInstance(getElement().getProject()).findPackage("");
      return rootPackage == null ? variants : ArrayUtil.mergeArrays(variants, rootPackage.getSubPackages());
    }
    return variants;
  }

  private boolean isInUsingStatement() {
    return UsefulPsiTreeUtil.getParentOfType(this, HaxeUsingStatement.class) != null;
  }

  private boolean isInImportStatement() {
    return UsefulPsiTreeUtil.getParentOfType(this, HaxeImportStatement.class) != null;
  }

  private void addChildClassVariants(Set<HaxeComponentName> variants, HaxeClass haxeClass) {
    if (haxeClass != null) {
      PsiFile psiFile = haxeClass.getContainingFile();
      VirtualFile virtualFile = psiFile.getVirtualFile();

      if (virtualFile != null) {
        String nameWithoutExtension = virtualFile.getNameWithoutExtension();

        String name = haxeClass.getName();
        if (name != null && name.equals(nameWithoutExtension)) {
          List<HaxeClass> haxeClassList = HaxeResolveUtil.findComponentDeclarations(psiFile);

          for (HaxeClass aClass : haxeClassList) {
            if (!aClass.getName().equals(nameWithoutExtension)) {
              variants.add(aClass.getComponentName());
            }
          }
        }
      }
    }
  }

  @NotNull
  private static HaxeClassResolveResult tryGetLeftResolveResult(HaxeExpression expression) {
    final HaxeReference leftReference = PsiTreeUtil.getChildOfType(expression, HaxeReference.class);
    return leftReference != null
           ? leftReference.resolveHaxeClass()
           : HaxeClassResolveResult.create(PsiTreeUtil.getParentOfType(expression, HaxeClass.class));
  }

  @Nullable
  private static String getLiteralClassName(IElementType type) {
    if (type == HaxeTokenTypes.STRING_LITERAL_EXPRESSION) {
      return "String";
    } else if (type == HaxeTokenTypes.ARRAY_LITERAL) {
      return "Array";
    } else if (type == HaxeTokenTypes.LITFLOAT) {
      return "Float";
    } else if (type == HaxeTokenTypes.REG_EXP) {
      return "EReg";
    } else if (type == HaxeTokenTypes.LITHEX || type == HaxeTokenTypes.LITINT || type == HaxeTokenTypes.LITOCT) {
      return "Int";
    }
    return null;
  }

  @NotNull
  private static JavaResolveResult[] toCandidateInfoArray(List<? extends PsiElement> elements) {
    final JavaResolveResult[] result = new JavaResolveResult[elements.size()];
    for (int i = 0, size = elements.size(); i < size; i++) {
      result[i] = new CandidateInfo(elements.get(i), EmptySubstitutor.getInstance());
    }
    return result;
  }

  private static void addUsingVariants(Set<HaxeComponentName> variants,
                                       Set<HaxeComponentName> variantsWithExtension,
                                       final @Nullable HaxeClass ourClass,
                                       HaxeReferenceImpl reference) {

    if (ourClass == null) return;

    HaxeFileModel.fromElement(reference).getUsingModels().stream()
      .flatMap(model -> model.getExtensionMethods(ourClass).stream())
      .map(HaxeMemberModel::getNamePsi)
      .forEach(name -> {
        variants.add(name);
        variantsWithExtension.add(name);
      });
  }

  private static void addClassVariants(Set<HaxeComponentName> suggestedVariants, @Nullable HaxeClass haxeClass, boolean filterByAccess,
                                       @Nullable HaxeGenericResolver resolver) {
    if (haxeClass == null) {
      return;
    }
    for (HaxeNamedComponent namedComponent : HaxeResolveUtil.findNamedSubComponents(resolver, haxeClass)) {
      final boolean needFilter = filterByAccess && !namedComponent.isPublic();
      if (!needFilter && namedComponent.getComponentName() != null) {
        suggestedVariants.add(namedComponent.getComponentName());
      }
    }
  }

  private static void addAbstractUnderlyingClassVariants(Set<HaxeComponentName> suggestedVariants,
                                                         @Nullable HaxeClass haxeClass, @Nullable HaxeGenericResolver resolver) {
    if (haxeClass == null || !haxeClass.isAbstract()) return;

    final HaxeAbstractClassModel model = (HaxeAbstractClassModel)haxeClass.getModel();
    final HaxeClass underlyingClass = model.getUnderlyingClass(resolver);
    if (underlyingClass != null) {
      addClassVariants(suggestedVariants, underlyingClass, true, resolver);
    }
  }

  private static void addClassStaticMembersVariants(@NotNull final Set<HaxeComponentName> suggestedVariants,
                                                    @NotNull final HaxeClass haxeClass,
                                                    boolean filterByAccess) {

    final boolean isEnum = haxeClass.isEnum();

    List<HaxeComponentName> staticMembers = haxeClass.getModel().getMembersSelf().stream()
      .filter(member -> (isEnum && member instanceof HaxeEnumValueModel) || member.isStatic())
      .filter(member -> !filterByAccess || member.isPublic())
      .map(HaxeMemberModel::getNamePsi)
      .collect(Collectors.toList());

    suggestedVariants.addAll(staticMembers);
  }

  private void addClassNonStaticMembersVariants(Set<HaxeComponentName> suggestedVariants,
                                                       @Nullable HaxeClass haxeClass,
                                                       @Nullable HaxeGenericResolver resolver,
                                                       boolean filterByAccess) {
    if (haxeClass == null) {
      return;
    }

    HaxeClassModel classModel = haxeClass.getModel();

    boolean extern = haxeClass.isExtern();
    boolean isAbstractEnum = haxeClass.isAbstract() && haxeClass.isEnum();
    boolean isAbstractForward = haxeClass.isAbstract() && ((HaxeAbstractClassModel)classModel).hasForwards();

    if (isAbstractForward) {
      final List<HaxeNamedComponent> forwardingHaxeNamedComponents =
        HaxeAbstractForwardUtil.findAbstractForwardingNamedSubComponents(haxeClass, resolver);
      if (forwardingHaxeNamedComponents != null) {
        for (HaxeNamedComponent namedComponent : forwardingHaxeNamedComponents) {
          final boolean needFilter = filterByAccess && !namedComponent.isPublic();
          if ((extern || !needFilter) &&
              !namedComponent.isStatic() &&
              namedComponent.getComponentName() != null &&
              !isConstructor(namedComponent)) {
            suggestedVariants.add(namedComponent.getComponentName());
          }
        }
      }
    }

    for (HaxeNamedComponent namedComponent : HaxeResolveUtil.findNamedSubComponents(resolver, haxeClass)) {
      final boolean needFilter = filterByAccess && !namedComponent.isPublic();
      if (isAbstractEnum && HaxeAbstractEnumUtil.couldBeAbstractEnumField(namedComponent)) {
        continue;
      }
      if ((extern || !needFilter) &&
          !namedComponent.isStatic() &&
          namedComponent.getComponentName() != null &&
          !isConstructor(namedComponent)) {
        suggestedVariants.add(namedComponent.getComponentName());
      }
    }
  }

  private static boolean isConstructor(HaxeNamedComponent component) {
    return component instanceof HaxeMethodPsiMixin && ((HaxeMethodPsiMixin)component).isConstructor();
  }

  /* Determine if the element to the right of the given element in the AST
   * (at the same level) is a dot '.' separator.
   * Workhorse for getQualifier().
   * XXX: If we use this more than once, move it to a utility class, such as UsefulPsiTreeUtil.
   */
  private static boolean nextSiblingIsADot(PsiElement element) {
    if (null == element) return false;

    PsiElement next = element.getNextSibling();
    ASTNode node = ((null != next) ? next.getNode() : null);
    IElementType type = ((null != node) ? node.getElementType() : null);
    boolean ret = (null != type && type.equals(HaxeTokenTypes.ODOT));
    return ret;
  }

  @Nullable
  @Override
  public PsiElement getReferenceNameElement() {
    PsiElement name = findChildByType(HaxeTokenTypes.IDENTIFIER);
    if (name == null) name = getLastChild();
    return name;
  }

  @Nullable
  @Override
  public PsiReferenceParameterList getParameterList() {
    // TODO:  Unimplemented.
    LOG.warn("getParameterList is unimplemented");

    // REFERENCE_PARAMETER_LIST  in Java
    HaxeTypeParam child = (HaxeTypeParam)findChildByType(HaxeTokenTypes.TYPE_PARAM);
    //return child == null ? null : child.getTypeList();
    return null;
  }

  @NotNull
  @Override
  public PsiType[] getTypeParameters() {
    // TODO:  Unimplemented.
    LOG.warn("getTypeParameters is unimplemented");
    return new PsiType[0];
  }

  @Override
  public boolean isQualified() {
    return null != getQualifier();
  }

  @Override
  public String getQualifiedName() {
    return JavaSourceUtil.getReferenceText(this);
  }

  @Override
  public void processVariants(@NotNull PsiScopeProcessor processor) {
    // TODO:  Unimplemented.
    LOG.warn("processVariants is unimplemented");
  }

  @Nullable
  @Override
  public PsiElement getQualifier() {
    PsiElement expression = getFirstChild();
    return expression != null && expression instanceof HaxeReference ? expression : null;
  }

  @Nullable
  @Override
  public String getReferenceName() {
    PsiElement nameElement = getReferenceNameElement();
    return nameElement == null ? getText() : nameElement.getText();
  }

  // PsiExpression implementations

  @Nullable
  public PsiType getPsiType() {
    // XXX: EMB: Not sure about this.  Does a reference really have a sub-node giving the type?
    HaxeType ht = findChildByClass(HaxeType.class);
    return ((null == ht) ? null : ht.getPsiType());
  }

  // PsiExpression implementations

  //@Nullable
  //public PsiExpression getQualifierExpression() {
  //  final PsiElement qualifier = getQualifier();
  //  return qualifier instanceof PsiExpression ? (PsiExpression)qualifier : null;
  //}

  public String toDebugString() {
    String ss = super.toString();
    // Unit tests don't want the extra data.  (Maybe we should fix the goldens?)
    String clazzName = this.getClass().getSimpleName();
    String text = getCanonicalText();
    ss += ":" + defaultIfEmpty(text, "<no text>");
    ss += ":" + defaultIfEmpty(clazzName, "<anonymous>");
    return ss;
  }

  @Override
  public String toString() {
    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      return toDebugString();
    }

    // Unit tests don't want the extra data.  (Maybe we should fix the goldens?)
    String ss = super.toString();
    return ss;
  }

  public String traceMsg(String message) {
    StringBuilder msg = new StringBuilder();
    String nodeText = this.getText();
    msg.append(null != nodeText ? nodeText : "<no text>");
    msg.append(':');
    if (null != message) {
      msg.append(message);
    }
    return HaxeDebugUtil.traceMessage(msg.toString(), 2048);
  }

  // HaxeLiteralExpression
  @Nullable
  @Override
  public HaxeBlockStatement getBlockStatement() {
    return HaxeStatementUtils.getBlockStatement(this);
  }
}