text:
/*	$NetBSD: npf_state.c,v 1.6.4.8 2013/02/11 21:49:49 riz Exp $	*/

/*-
 * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This material is based upon work partially supported by The
 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * NPF state engine to track sessions.
 */

#include <special_includes/sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.6.4.8 2013/02/11 21:49:49 riz Exp $");

#include <special_includes/sys/param.h>
#include <special_includes/sys/systm.h>

#include <special_includes/sys/mutex.h>

#include "npf_impl.h"

/*
 * Generic session states and timeout table.
 *
 * Note: used for connection-less protocols.
 */

#define	NPF_ANY_SESSION_CLOSED		0
#define	NPF_ANY_SESSION_NEW		1
#define	NPF_ANY_SESSION_ESTABLISHED	2
#define	NPF_ANY_SESSION_NSTATES		3

static const int npf_generic_fsm[NPF_ANY_SESSION_NSTATES][2] = {
	[NPF_ANY_SESSION_CLOSED] = {
		[NPF_FLOW_FORW]		= NPF_ANY_SESSION_NEW,
	},
	[NPF_ANY_SESSION_NEW] = {
		[NPF_FLOW_FORW]		= NPF_ANY_SESSION_NEW,
		[NPF_FLOW_BACK]		= NPF_ANY_SESSION_ESTABLISHED,
	},
	[NPF_ANY_SESSION_ESTABLISHED] = {
		[NPF_FLOW_FORW]		= NPF_ANY_SESSION_ESTABLISHED,
		[NPF_FLOW_BACK]		= NPF_ANY_SESSION_ESTABLISHED,
	},
};

static u_int npf_generic_timeout[] __read_mostly = {
	[NPF_ANY_SESSION_CLOSED]	= 0,
	[NPF_ANY_SESSION_NEW]		= 30,
	[NPF_ANY_SESSION_ESTABLISHED]	= 60,
};

/*
 * State sampler for debugging.
 */
#if defined(_NPF_TESTING)
static void (*npf_state_sample)(npf_state_t *, bool) = NULL;
#define	NPF_STATE_SAMPLE(n, r) if (npf_state_sample) (*npf_state_sample)(n, r);
#else
#define	NPF_STATE_SAMPLE(n, r)
#endif

/*
 * npf_state_init: initialise the state structure.
 *
 * Should normally be called on a first packet, which also determines the
 * direction in a case of connection-orientated protocol.  Returns true on
 * success and false otherwise (e.g. if protocol is not supported).
 */
bool
npf_state_init(npf_cache_t *npc, nbuf_t *nbuf, npf_state_t *nst)
{
	const int proto = npc->npc_proto;
	bool ret;

	KASSERT(npf_iscached(npc, NPC_IP46));
	KASSERT(npf_iscached(npc, NPC_LAYER4));

	memset(nst, 0, sizeof(npf_state_t));
	mutex_init(&nst->nst_lock, MUTEX_DEFAULT, IPL_SOFTNET);

	switch (proto) {
	case IPPROTO_TCP:
		/* Pass to TCP state tracking engine. */
		ret = npf_state_tcp(npc, nbuf, nst, NPF_FLOW_FORW);
		break;
	case IPPROTO_UDP:
	case IPPROTO_ICMP:
		/* Generic. */
		nst->nst_state = npf_generic_fsm[nst->nst_state][NPF_FLOW_FORW];
		ret = true;
		break;
	default:
		ret = false;
	}
	NPF_STATE_SAMPLE(nst, ret);
	return ret;
}

void
npf_state_destroy(npf_state_t *nst)
{

	nst->nst_state = 0;
	mutex_destroy(&nst->nst_lock);
}

/*
 * npf_state_inspect: inspect the packet according to the protocol state.
 *
 * Return true if packet is considered to match the state (e.g. for TCP,
 * the packet belongs to the tracked connection) and false otherwise.
 */
bool
npf_state_inspect(npf_cache_t *npc, nbuf_t *nbuf,
    npf_state_t *nst, const bool forw)
{
	const int proto = npc->npc_proto;
	const int di = forw ? NPF_FLOW_FORW : NPF_FLOW_BACK;
	bool ret;

	mutex_enter(&nst->nst_lock);
	switch (proto) {
	case IPPROTO_TCP:
		/* Pass to TCP state tracking engine. */
		ret = npf_state_tcp(npc, nbuf, nst, di);
		break;
	case IPPROTO_UDP:
	case IPPROTO_ICMP:
		/* Generic. */
		nst->nst_state = npf_generic_fsm[nst->nst_state][di];
		ret = true;
		break;
	default:
		ret = false;
	}
	NPF_STATE_SAMPLE(nst, ret);
	mutex_exit(&nst->nst_lock);

	return ret;
}

/*
 * npf_state_etime: return session expiration time according to the state.
 */
int
npf_state_etime(const npf_state_t *nst, const int proto)
{
	const int state = nst->nst_state;
	int timeout = 0;

	switch (proto) {
	case IPPROTO_TCP:
		/* Pass to TCP state tracking engine. */
		timeout = npf_state_tcp_timeout(nst);
		break;
	case IPPROTO_UDP:
	case IPPROTO_ICMP:
		/* Generic. */
		timeout = npf_generic_timeout[state];
		break;
	default:
		KASSERT(false);
	}
	return timeout;
}

void
npf_state_dump(const npf_state_t *nst)
{
#if defined(DDB) || defined(_NPF_TESTING)
	const npf_tcpstate_t *fst = &nst->nst_tcpst[0];
	const npf_tcpstate_t *tst = &nst->nst_tcpst[1];

	printf("\tstate (%p) %d:\n\t\t"
	    "F { end %u maxend %u mwin %u wscale %u }\n\t\t"
	    "T { end %u maxend %u mwin %u wscale %u }\n",
	    nst, nst->nst_state,
	    fst->nst_end, fst->nst_maxend, fst->nst_maxwin, fst->nst_wscale,
	    tst->nst_end, tst->nst_maxend, tst->nst_maxwin, tst->nst_wscale
	);
#endif
}

#if defined(_NPF_TESTING)
void
npf_state_setsampler(void (*func)(npf_state_t *, bool))
{
	npf_state_sample = func;
}
#endif


text:
title: bronx
tags: simple, default
author: katychuang
authorurl: http://twitter.com/katychuang
cover: bronx-index.png
screens: bronx-index, bronx-about, bronx-archive, bronx-contact, bronx-index
demo: http://katychuang.com/hakyll-cssgarden/themes/default/?theme=bronx
download: https://github.com/katychuang/hakyll-cssgarden/blob/master/default_theme/css/bronx.css
---

This is a simple theme for the default installation of Hakyll 4, that takes the full width of the page.

Here is another paragraph.

redpajama_set_name: RedPajamaGithub


text:
class AddPhoneToTickets < ActiveRecord::Migration[5.0]
  def change
    add_column :tickets, :phone, :string
  end
end


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetNuke.Services.Localization;

namespace Dnn.EditBar.UI.Helpers
{
    public static class LocalizationHelper
    {
        private const string ResourcesFile = "~/DesktopModules/admin/Dnn.EditBar/App_LocalResources/EditBar.resx";

        public static string GetString(string key, string resourcesFile = ResourcesFile)
        {
            return Localization.GetString(key, resourcesFile);
        }
    }
}


text:
#import "ObjectInformation.h"

@implementation ObjectInformation

@synthesize rawXml, replicas, retentionEnabled, retentionEnd, expirationEnabled,
    expirationEnd, selection, objectId, current;

#pragma mark Memory Management
- (void) dealloc {
    self.rawXml = nil;
    self.replicas = nil;
    self.retentionEnd = nil;
    self.expirationEnd = nil;
    self.selection = nil;
    self.objectId = nil;

    [super dealloc];
}

-(id) init {
    self = [super init];

    if(self) {
        self.replicas = [NSMutableArray array];
    }

    return self;
}

#pragma mark Convienence Methods
+ (id) objectInformation {
    return [[[ObjectInformation alloc] init] autorelease];
}

@end


text:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase
// Copyright (C) 2004 The jTDS Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
package net.sourceforge.jtds.jdbcx;

import java.sql.*;
import java.util.*;

import javax.sql.*;

import net.sourceforge.jtds.jdbc.*;
import net.sourceforge.jtds.jdbcx.proxy.*;

/**
 * jTDS implementation of the PooledConnection interface.
 *
 * @version $Id: PooledConnection.java,v 1.10 2004/12/19 09:40:23 alin_sinpalean Exp $
 */
public class PooledConnection implements javax.sql.PooledConnection {
    private final ArrayList listeners = new ArrayList();

    protected Connection connection;

    public PooledConnection(Connection connection) {
        this.connection = connection;
    }

    /**
     * Adds the specified listener to the list.
     *
     * @see #fireConnectionEvent
     * @see #removeConnectionEventListener
     */
    public synchronized void addConnectionEventListener(ConnectionEventListener listener) {
        listeners.add(listener);
    }

    /**
     * Closes the database connection.
     *
     * @throws SQLException if an error occurs
     */
    public synchronized void close() throws SQLException {
        connection.close();
        connection = null; // Garbage collect the connection
    }

    /**
     * Fires a new connection event on all listeners.
     *
     * @param closed true if close has been called on the
     *        connection; false if the sqlException represents
     *        an error where the connection may not longer be used.
     * @param sqlException the SQLException to pass to the listeners
     */
    public synchronized void fireConnectionEvent(boolean closed, SQLException sqlException) {
        if (listeners.size() > 0) {
            ConnectionEvent connectionEvent = new ConnectionEvent(this, sqlException);
            Iterator iterator = listeners.iterator();

            while (iterator.hasNext()) {
                ConnectionEventListener listener = (ConnectionEventListener) iterator.next();

                if (closed) {
                    listener.connectionClosed(connectionEvent);
                } else {
                    try {
                        if (connection == null || connection.isClosed()) {
                            listener.connectionErrorOccurred(connectionEvent);
                        }
                    } catch (SQLException ex) {
                        // Will never occur
                    }
                }
            }
        }
    }

    /**
     * Returns a ConnectionProxy.
     *
     * @throws SQLException if an error occurs
     */
    public synchronized Connection getConnection() throws SQLException {
        if (connection == null) {
            fireConnectionEvent(false,
                new SQLException(Messages.get("error.jdbcx.conclosed"),
                                 "08003"));

            return null;
        }

        // Should the SQLException be captured here for safety in the future even though
        // no SQLException is being thrown by the ConnectionProxy at the moment???
        return new ConnectionProxy(this, connection);
    }

    /**
     * Removes the specified listener from the list.
     *
     * @see #addConnectionEventListener
     * @see #fireConnectionEvent
     */
    public synchronized void removeConnectionEventListener(ConnectionEventListener listener) {
        listeners.remove(listener);
    }

	@Override
	public void addStatementEventListener(StatementEventListener arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeStatementEventListener(StatementEventListener arg0) {
		// TODO Auto-generated method stub

	}
}


text:
using java.lang;
using java.util;
using org.eclipse.jface.text;
using org.eclipse.jface.text.contentassist;
using org.eclipse.jface.text.source;
using stab.query;
using stab.reflection;
using cnatural.compiler;
using cnatural.helpers;
using cnatural.parser;
using cnatural.syntaxtree;

namespace cnatural.eclipse.editors {

	public class ContentAssistProcessor : IContentAssistProcessor {
		private static final ICompletionProposal[] EMPTY_PROPOSALS = CompletionProposalHelper.createEmpty();
		private static final Iterable<String> STATEMENT_TEXTS = new ArrayList<String> {
			"bool", "boolean", "byte", "char", "do", "double", "float", "for", "foreach", "if", "int",
			"long", "new", "return", "short", "string", "super", "synchronized", "this", "using", "while" };
		private static final Iterable<String> EXPRESSION_TEXTS = new ArrayList<String> {
			"false", "instanceof", "new", "null", "sizeof", "super", "this", "true", "typeof" };
		private static final Iterable<String> TYPE_TEXTS = new ArrayList<String> {
			"bool", "boolean", "byte", "char", "delegate", "double", "float", "int", "long", "short", "string" };

		private SourceEditor editor;
		private ISourceViewer sourceViewer;

		private bool inEditedText;
		private int actualOffset;
		private int actualTokenIndex;
		private Token actualToken;
		private int offset;
		private int tokenIndex;
		private Token token;
		private char[] text;
		private List<Token> tokens;
		private ContentAssistContext context;
		private StatementProcessor statementProcessor;
		private ExpressionProcessor expressionProcessor;

		public ContentAssistProcessor(SourceEditor editor, ISourceViewer sourceViewer) {
			this.editor = editor;
			this.sourceViewer = sourceViewer;
			this.statementProcessor = new StatementProcessor(this);
			this.expressionProcessor = new ExpressionProcessor(this);
		}

		public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
			return null;
		}

		public char[] getContextInformationAutoActivationCharacters() {
			return null;
		}

		public String getErrorMessage() {
			return null;
		}

		public IContextInformationValidator getContextInformationValidator() {
			return null;
		}

		public char[] getCompletionProposalAutoActivationCharacters() {
			return null;
		}

		public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
			Environment.trace(this, "compute completion");
			var t0 = System.nanoTime();

			var file = editor.getFile();
			if (file == null) {
				Environment.trace(this, "no file");
				return EMPTY_PROPOSALS;
			}

			var projectManager = Environment.getProjectManager(file);
			if (projectManager == null) {
				Environment.trace(this, "not a project with Stab nature");
				return EMPTY_PROPOSALS;
			}

			var highlighter = editor.Highlighter;
			if (highlighter == null) {
				Environment.trace(this, "no highlighter");
				return EMPTY_PROPOSALS;
			}

			var tokens = highlighter.Tokens;
			if (tokens == null || tokens.size() == 0) {
				Environment.trace(this, "no tokens");
				return EMPTY_PROPOSALS;
			}

			var tokenIndex = Highlighter.getPositionIndex(tokens, offset);
			if (tokenIndex == -1) {
				Environment.trace(this, "no token at " + offset);
				return EMPTY_PROPOSALS;
			}

			var token = tokens[tokenIndex];
			var beforeToken = token.offset == offset;

			Environment.trace(this, "token " + token.LexicalUnit + " " + token.IsUpdated);

			if (token.SemanticStyle != null && !beforeToken) {
				switch (token.SemanticStyle) {
				case Preprocessor:
				case SkippedSource:
					Environment.trace(this, "in preprocessor part");
					return EMPTY_PROPOSALS;
				case DelimitedComment:
				case SingleLineComment:
					Environment.trace(this, "in comment");
					return EMPTY_PROPOSALS;
				}
			}
			if (token.LexicalUnit == LexicalUnit.NewLine) {
				if (tokenIndex > 0 && tokens[tokenIndex - 1].LexicalUnit == LexicalUnit.SingleLineComment) {
					Environment.trace(this, "in comment");
					return EMPTY_PROPOSALS;
				}
			}

			var compilationUnit = highlighter.CompilationUnit;
			if (compilationUnit == null) {
				Environment.trace(this, "no AST");
				return EMPTY_PROPOSALS;
			}

			this.inEditedText = token.IsUpdated || (beforeToken && tokenIndex > 0 && tokens[tokenIndex - 1].IsUpdated);
			this.actualOffset = offset;
			this.actualTokenIndex = tokenIndex;
			this.actualToken = token;
			if (this.inEditedText) {
				var tk = tokens[--tokenIndex];
				while (tokenIndex > 0) {
					if (tokens[tokenIndex - 1].IsUpdated) {
						tk = tokens[--tokenIndex];
					} else {
						break;
					}
				}
				this.offset = tk.offset;
				this.token = tk;
			} else {
				this.offset = offset;
				this.token = token;
			}
			this.tokenIndex = tokenIndex;
			this.tokens = tokens;
			this.text = highlighter.Text;
			this.context = new ContentAssistContext(highlighter.TypeSystem, highlighter.AnnotatedTypeSystem);

			var result = computeCompletionProposalsInPackage(Query.empty<String>(), compilationUnit.Body);
			Environment.trace(this, "compute completion done in " + ((System.nanoTime() - t0) / 1e6) + "ms");
			return result;
		}

		private ICompletionProposal[] computeCompletionProposalsInPackage(Iterable<String> names, PackageBodyNode body) {
			var beforeMembers = true;
			if (body != null) {
				foreach (var u in body.UsingDirectives) {
					var bounds = u.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(offset)) {
						break;
					}
					if (bounds.isBeforeOffset(offset)) {
						continue;
					}

					// TODO
					Environment.trace(this, "using");
					return EMPTY_PROPOSALS;
				}

				context.enterPackage(names, body);

				foreach (var m in body.Members) {
					var bounds = ((SyntaxNode)m).getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(offset)) {
						break;
					}
					beforeMembers = false;
					if (bounds.isBeforeOffset(offset)) {
						continue;
					}
					switch (m.PackageMemberKind) {
					case Package:
						var pkg = (PackageDeclarationNode)m;
						return computeCompletionProposalsInPackage(pkg.Identifiers.select(p => p.getUserData(typeof(String))), pkg.Body);
					case Class:
						return computeCompletionProposalsInClass((ClassDeclarationNode)m);
					case Interface:
						return computeCompletionProposalsInInterface((InterfaceDeclarationNode)m);
					case Delegate:
						return computeCompletionProposalsInDelegate((DelegateDeclarationNode)m);
					}
				}
				if (beforeMembers) {
				}
			}

			// TODO
			Environment.trace(this, "package " + beforeMembers);
			return EMPTY_PROPOSALS;
		}

		private ICompletionProposal[] computeCompletionProposalsInClass(ClassDeclarationNode declaration) {
			var beforeMembers = true;
			foreach (var m in declaration.Members) {
				var bounds = ((SyntaxNode)m).getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				beforeMembers = false;
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}
				context.enterClass(declaration);
				switch (m.TypeMemberKind) {
				case Class:
					return computeCompletionProposalsInClass((ClassDeclarationNode)m);
				case Interface:
					return computeCompletionProposalsInInterface((InterfaceDeclarationNode)m);
				case Delegate:
					return computeCompletionProposalsInDelegate((DelegateDeclarationNode)m);
				case Method:
					return computeCompletionProposalsInMethod((MethodDeclarationNode)m);
				case Property:
					return computeCompletionProposalsInProperty((PropertyDeclarationNode)m);
				case Indexer:
					return computeCompletionProposalsInIndexer((IndexerDeclarationNode)m);
				case Constructor:
					return computeCompletionProposalsInConstructor((ConstructorDeclarationNode)m);
				case Destructor:
					return computeCompletionProposalsInDestructor((DestructorDeclarationNode)m);
				case Field:
					return computeCompletionProposalsInField((FieldDeclarationNode)m);
				case EnumConstant:
					return computeCompletionProposalsInEnumConstant((EnumConstantDeclarationNode)m);
				}
			}

			// TODO
			Environment.trace(this, "class " + beforeMembers);
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInInterface(InterfaceDeclarationNode declaration) {
			var beforeMembers = true;
			foreach (var m in declaration.Members) {
				var bounds = ((SyntaxNode)m).getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				beforeMembers = false;
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}
				context.enterInterface(declaration);
				switch (m.TypeMemberKind) {
				case Method:
					return computeCompletionProposalsInMethod((MethodDeclarationNode)m);
				case Property:
					return computeCompletionProposalsInProperty((PropertyDeclarationNode)m);
				case Indexer:
					return computeCompletionProposalsInIndexer((IndexerDeclarationNode)m);
				}
			}

			// TODO
			Environment.trace(this, "interface " + beforeMembers);
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInDelegate(DelegateDeclarationNode declaration) {

			// TODO
			Environment.trace(this, "delegate");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInMethod(MethodDeclarationNode declaration) {
			var m = declaration.getUserData(typeof(MethodInfo));
			if (containsOffset(declaration.ReturnType)) {
				return computeCompletionProposalsInType(declaration.ReturnType, m.ReturnType);
			}
			var pit = m.Parameters.iterator();
			foreach (var p in declaration.Parameters) {
				var pt = pit.next().Type;

				var bounds = p.getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}

				if (containsOffset(p.Type)) {
					return computeCompletionProposalsInType(p.Type, pt);
				}

				Environment.trace(this, "method parameter");
				return computeCompletionProposalsOutsideExpression(declaration);
			}
			var body = declaration.Body;
			if (body != null && containsOffset(body)) {
				context.enterMethod(declaration);
				return statementProcessor.handleStatement(body, null);
			}

			// TODO
			Environment.trace(this, "method");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInProperty(PropertyDeclarationNode declaration) {
			var get = declaration.GetAccessor;
			var set = declaration.SetAccessor;
			TypeInfo t = null;
			if (get != null) {
				var m = get.getUserData(typeof(MethodInfo));
				t = m.ReturnType;
			} else if (set != null) {
				var m = set.getUserData(typeof(MethodInfo));
				t = m.Parameters.first().Type;
			}

			if (containsOffset(declaration.Type)) {
				return computeCompletionProposalsInType(declaration.Type, t);
			}
			if (get != null && containsOffset(get)) {
				var body = get.Body;
				if (body != null && containsOffset(body)) {
					context.enterPropertyGetter(declaration);
					return statementProcessor.handleStatement(body, null);
				}

				// TODO
				Environment.trace(this, "property getter");
				return EMPTY_PROPOSALS;
			}
			if (set != null && containsOffset(set)) {
				var body = set.Body;
				if (body != null && containsOffset(body)) {
					context.enterPropertySetter(declaration);
					return statementProcessor.handleStatement(body, null);
				}

				// TODO
				Environment.trace(this, "property setter");
				return EMPTY_PROPOSALS;
			}

			// TODO
			Environment.trace(this, "property");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInIndexer(IndexerDeclarationNode declaration) {
			var get = declaration.GetAccessor;
			var set = declaration.SetAccessor;
			TypeInfo t = null;
			MethodInfo m = null;
			if (get != null) {
				m = get.getUserData(typeof(MethodInfo));
				t = m.ReturnType;
			} else if (set != null) {
				m = set.getUserData(typeof(MethodInfo));
				t = m.Parameters.last().Type;
			}

			if (containsOffset(declaration.Type)) {
				return computeCompletionProposalsInType(declaration.Type, t);
			}

			var pit = m.Parameters.iterator();
			foreach (var p in declaration.Parameters) {
				var pt = pit.next().Type;

				var bounds = p.getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}

				if (containsOffset(p.Type)) {
					return computeCompletionProposalsInType(p.Type, pt);
				}

				Environment.trace(this, "indexer parameter");
				return EMPTY_PROPOSALS;
			}
			var accessor = declaration.GetAccessor;
			if (accessor != null && containsOffset(accessor)) {
				var body = accessor.Body;
				if (body != null && containsOffset(body)) {
					context.enterIndexerGetter(declaration);
					return statementProcessor.handleStatement(body, null);
				}

				// TODO
				Environment.trace(this, "indexer getter");
				return EMPTY_PROPOSALS;
			}
			accessor = declaration.SetAccessor;
			if (accessor != null && containsOffset(accessor)) {
				var body = accessor.Body;
				if (body != null && containsOffset(body)) {
					context.enterIndexerSetter(declaration);
					return statementProcessor.handleStatement(body, null);
				}

				// TODO
				Environment.trace(this, "indexer setter");
				return EMPTY_PROPOSALS;
			}

			// TODO
			Environment.trace(this, "indexer");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInConstructor(ConstructorDeclarationNode declaration) {
			var pit = declaration.getUserData(typeof(MethodInfo)).Parameters.iterator();
			foreach (var p in declaration.Parameters) {
				var pt = pit.next().Type;

				var bounds = p.getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}

				if (containsOffset(p.Type)) {
					return computeCompletionProposalsInType(p.Type, pt);
				}

				Environment.trace(this, "constructor parameter");
				return computeCompletionProposalsOutsideExpression(declaration);
			}

			var body = declaration.Body;
			if (body != null && containsOffset(body)) {
				context.enterConstructor(declaration);
				return statementProcessor.handleStatement(body, null);
			}

			Environment.trace(this, "constructor");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInDestructor(DestructorDeclarationNode declaration) {
			var body = declaration.Body;
			if (body != null && containsOffset(body)) {
				return statementProcessor.handleStatement(body, null);
			}

			Environment.trace(this, "destructor");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInField(FieldDeclarationNode declaration) {
			var f = declaration.Declarators[0].getUserData(typeof(FieldInfo));

			if (containsOffset(declaration.Type)) {
				return computeCompletionProposalsInType(declaration.Type, f.Type);
			}

			foreach (var decl in declaration.Declarators) {
				var bounds = decl.getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}

				Environment.trace(this, "field declarator");
				if (decl.Value != null) {
					return expressionProcessor.handleExpression(decl.Value, null, true);
				}
				return EMPTY_PROPOSALS;
			}

			Environment.trace(this, "field");
			return computeCompletionProposalsOutsideExpression(declaration);
		}

		private ICompletionProposal[] computeCompletionProposalsInEnumConstant(EnumConstantDeclarationNode declaration) {
			foreach (var e in declaration.Arguments) {
				var bounds = e.getUserData(typeof(SyntaxNodeBounds));
				if (bounds == null || bounds.isAfterOffset(offset)) {
					break;
				}
				if (bounds.isBeforeOffset(offset)) {
					continue;
				}
				return expressionProcessor.handleExpression(e, null, true);
			}

			Environment.trace(this, "enum constant");
			return EMPTY_PROPOSALS;
		}

		private ICompletionProposal[] computeCompletionProposalsInSimpleType(TypeReferenceNode type) {
			var token = this.token;
			if (token.offset == offset) {
				token = tokens[tokenIndex - 1];
			}
			var length = token.length - (offset - token.offset);
			var prefix = new String(text, token.offset, offset - token.offset);
			return CompletionProposalHelper.createCompletionProposals(offset, length, prefix, context.getRootPackages(),
					context.getTypeMembers(), TYPE_TEXTS);
		}

		private ICompletionProposal[] computeCompletionProposalsInType(TypeReferenceNode type, TypeInfo Type) {
			Environment.trace(this, "type");

			if (inEditedText) {
				Environment.trace(this, "edited type");
				return EMPTY_PROPOSALS;
			}

			switch (type.TypeReferenceKind) {
			case Boolean:
			case Byte:
			case Char:
			case Double:
			case Float:
			case Int:
			case Long:
			case Short:
			case Void:
				return computeCompletionProposalsInSimpleType(type);

			case SimpleName:
				var simple = (SimpleNameTypeReferenceNode)type;
				var bounds = simple.getUserData(typeof(SyntaxNodeBounds));
				var nameToken = bounds.StartToken;
				if (offset <= nameToken.offset + nameToken.length) {
					return computeCompletionProposalsInSimpleType(type);
				} else {
					var ait = Type.GenericArguments.iterator();
					foreach (var arg in simple.TypeArguments) {
						var at = ait.next();

						bounds = arg.getUserData(typeof(SyntaxNodeBounds));
						if (bounds == null || bounds.isAfterOffset(offset)) {
							break;
						}
						if (bounds.isBeforeOffset(offset)) {
							continue;
						}
						return computeCompletionProposalsInType(arg, at);
					}
					break;
				}

			case Qualified:
				var qualified = (QualifiedTypeReferenceNode)type;
				if (containsOffset(qualified.SimpleName)) {
					String prefix;
					int length;
					if (offset == token.offset) {
						var tk = tokens[tokenIndex - 1];
						length = 0;
						prefix = new String(text, tk.offset, tk.length);
					} else {
						length = token.length - (offset - token.offset);
						prefix = new String(text, token.offset, offset - token.offset);
					}
					Iterable<MemberInfo> typeMembers;
					if (Type.DeclaringType == null) {
						typeMembers = context.getTypeMembers().where(p => p.Type.PackageName.equals(Type.PackageName));
					} else {
						typeMembers = context.getTypeMembers().where(p => p.Type.DeclaringType == Type.DeclaringType);
					}
					return CompletionProposalHelper.createCompletionProposals(offset, length, prefix, Query.empty<String>(),
							typeMembers, TYPE_TEXTS);
				} else if (containsOffset(qualified.EnclosingType)) {
					if (Type.DeclaringType != null) {
						return computeCompletionProposalsInType(qualified.EnclosingType, Type.DeclaringType);
					}
				}
				break;

			case Array:
				var arrayType = (ArrayTypeReferenceNode)type;
				if (containsOffset(arrayType.ElementType)) {
					return computeCompletionProposalsInType(arrayType.ElementType, Type.ElementType);
				}
				break;

			case LowerBoundedWildcard:
			case UpperBoundedWildcard:
				var wildcard = (WildcardTypeReferenceNode)type;
				if (containsOffset(wildcard.Bound)) {
					return computeCompletionProposalsInType(wildcard.Bound, Type.WildcardBound);
				}
				break;
			}

			return CompletionProposalHelper.createCompletionProposals(offset, 0, "", context.getRootPackages(),
					context.getTypeMembers(), TYPE_TEXTS);
		}

		private ICompletionProposal[] computeCompletionProposalsInStatement(SyntaxNode syntaxNode) {
			return computeCompletionProposals(syntaxNode, false);
		}

		private ICompletionProposal[] computeCompletionProposalsInExpression(SyntaxNode syntaxNode) {
			return computeCompletionProposals(syntaxNode, true);
		}

		private ICompletionProposal[] computeCompletionProposals(SyntaxNode syntaxNode, bool expression) {
			var prefix = "";
			int length = 0;
			if (inEditedText) {
				var editedTokens = getEditedTokens(syntaxNode).toList();
				int size = editedTokens.size();
				if (size == 1 || (size > 1 && isExpressionSeparator(editedTokens[size - 2]))) {
					if (expression && editedTokens[size - 1].LexicalUnit == LexicalUnit.Dot) {
						var tinfo = syntaxNode.getUserData(typeof(ExpressionInfo));
						if (actualToken.offset < actualOffset) {
							length = actualToken.length - (actualOffset - actualToken.offset);
							prefix = new String(text, actualToken.offset, actualOffset - actualToken.offset);
						}
						return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix, Query.empty<String>(),
								context.getMembers(tinfo.Type, tinfo.Member != null && tinfo.Member.MemberKind == MemberKind.Type),
								Query.empty<String>());
					}
				} else if ((size == 2 || (size > 2 && isExpressionSeparator(editedTokens[size - 3]))) &&
						editedTokens[size - 1].LexicalUnit == LexicalUnit.Dot) {
					var tk = editedTokens[size - 2];
					switch (tk.LexicalUnit) {
					case Identifier:
					case Keyword:
					case ContextualKeyword:
						if (actualToken.offset < actualOffset) {
							length = actualToken.length - (actualOffset - actualToken.offset);
							prefix = new String(text, actualToken.offset, actualOffset - actualToken.offset);
						}
						var text = new String(text, tk.offset, tk.length);
						return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix, Query.empty<String>(),
								context.getMembers(text), Query.empty<String>());
					}
				} else if ((size == 3 || (size > 3 && isExpressionSeparator(editedTokens[size - 4]))) &&
						editedTokens[size - 2].LexicalUnit == LexicalUnit.Dot && actualToken.offset == actualOffset) {
					var tk = editedTokens[size - 3];
					switch (tk.LexicalUnit) {
					case Identifier:
					case Keyword:
					case ContextualKeyword:
						var tk2 = editedTokens[size - 1];
						switch (tk2.LexicalUnit) {
						case Identifier:
						case Keyword:
						case ContextualKeyword:
							prefix = new String(text, tk2.offset, actualOffset - tk2.offset);
							var text = new String(text, tk.offset, tk.length);
							return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix, Query.empty<String>(),
									context.getMembers(text), Query.empty<String>());
						}
						break;
					}
				}
			}

			var token = this.actualToken;
			if (token.offset == actualOffset) {
				token = tokens[actualTokenIndex - 1];
			}
			switch (token.LexicalUnit) {
			case Identifier:
			case Keyword:
			case ContextualKeyword:
				length = token.length - (actualOffset - token.offset);
				prefix = new String(text, token.offset, actualOffset - token.offset);
				break;
			}
			if (expression) {
				return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix,
						(length == 0) ? context.getRootPackages() : Query.empty<String>(),
						context.getMembers(), EXPRESSION_TEXTS);
			} else {
				return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix,
						(length == 0) ? context.getRootPackages() : Query.empty<String>(),
						context.getMembers(), STATEMENT_TEXTS);
			}
		}

		private ICompletionProposal[] computeCompletionProposalsOutsideExpression(SyntaxNode syntaxNode) {
			var prefix = "";
			int length = 0;
			if (inEditedText) {
				Environment.trace(this, "edited outside expression");
			}

			var token = this.actualToken;
			if (token.offset == actualOffset) {
				token = tokens[actualTokenIndex - 1];
			}
			switch (token.LexicalUnit) {
			case Identifier:
			case Keyword:
			case ContextualKeyword:
				length = token.length - (actualOffset - token.offset);
				prefix = new String(text, token.offset, actualOffset - token.offset);
				break;
			}
			return CompletionProposalHelper.createCompletionProposals(actualOffset, length, prefix,
					(length == 0) ? context.getRootPackages() : Query.empty<String>(),
					context.getTypeMembers(), TYPE_TEXTS);
		}

		private Iterable<Token> getEditedTokens(SyntaxNode syntaxNode) {
			for (int i = tokenIndex; i < actualTokenIndex; i++) {
				var tk = tokens[i];
				switch (tk.LexicalUnit) {
				case Whitespace:
				case DelimitedComment:
				case SingleLineComment:
				case NewLine:
					break;
				default:
					yield return tk;
					break;
				}
			}
		}

		private static bool isExpressionSeparator(Token token) {
			switch (token.LexicalUnit) {
			case Dot:
			case Identifier:
			case StringLiteral:
			case VerbatimIdentifier:
			case VerbatimStringLiteral:
				return false;
			case ContextualKeyword:
			case Keyword:
				switch (token.Keyword) {
				case Break:
				case Return:
					return true;
				default:
					return false;
				}
			default:
				return true;
			}
		}

		private bool containsOffset(SyntaxNode syntaxNode) {
			var bounds = syntaxNode.getUserData(typeof(SyntaxNodeBounds));
			if (bounds == null) {
				return false;
			}
			return bounds.containsOffset(offset);
		}

		private bool editedText(SyntaxNode syntaxNode) {
			var bounds = syntaxNode.getUserData(typeof(SyntaxNodeBounds));
			var startToken = bounds.StartToken;
			var endToken = bounds.EndToken;
			return endToken.offset + endToken.length - startToken.offset != syntaxNode.EndPosition - syntaxNode.StartPosition;
		}

		private bool isAfterEndToken(SyntaxNode syntaxNode) {
			var bounds = syntaxNode.getUserData(typeof(SyntaxNodeBounds));
			var endToken = bounds.EndToken;
			return endToken.offset + endToken.length == offset;
		}

		private Token getPreviousToken(int offset) {
			int index = Highlighter.getPositionIndex(tokens, offset);
			for (int i = index - 1; i >= 0; --i) {
				var token = tokens[i];
				switch (token.LexicalUnit) {
				case Whitespace:
				case DelimitedComment:
				case SingleLineComment:
				case NewLine:
					break;
				default:
					return token;
				}
			}
			return null;
		}

		private class StatementProcessor : StatementHandler<Void, ICompletionProposal[]> {
			private ContentAssistProcessor processor;

			StatementProcessor(ContentAssistProcessor processor)
					: super(false) {
				this.processor = processor;
			}

			protected override ICompletionProposal[] handleBlock(BlockStatementNode block, Void source) {
				foreach (var s in block.Statements) {
					var bounds = s.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						if (s.StatementKind == StatementKind.LocalDeclaration) {
							processor.context.declareLocals((LocalDeclarationStatementNode)s);
						}
					} else {
						return handleStatement(s, null);
					}
				}

				Environment.trace(this, "block");
				return processor.computeCompletionProposalsInStatement(block);
			}

			protected override ICompletionProposal[] handleBreak(BreakStatementNode breakStatement, Void source) {
				Environment.trace(this, "break");
				return processor.computeCompletionProposalsInStatement(breakStatement);
			}

			protected override ICompletionProposal[] handleContinue(ContinueStatementNode continueStatement, Void source) {
				Environment.trace(this, "continue");
				return processor.computeCompletionProposalsInStatement(continueStatement);
			}

			protected override ICompletionProposal[] handleDo(DoStatementNode doStatement, Void source) {
				if (processor.containsOffset(doStatement.Statement)) {
					return handleStatement(doStatement.Statement, null);
				}
				if (processor.containsOffset(doStatement.Condition)) {
					return processor.expressionProcessor.handleExpression(doStatement.Condition, null, true);
				}

				Environment.trace(this, "do");
				return processor.computeCompletionProposalsInStatement(doStatement);
			}

			protected override ICompletionProposal[] handleExpression(ExpressionStatementNode expression, Void source) {
				if (processor.containsOffset(expression.Expression)) {
					return processor.expressionProcessor.handleExpression(expression.Expression, null, false);
				}

				Environment.trace(this, "expression statement");
				if (processor.isAfterEndToken(expression)) {
					return processor.computeCompletionProposalsInStatement(expression);
				} else {
					return processor.computeCompletionProposalsInExpression(expression);
				}
			}

			protected override ICompletionProposal[] handleFor(ForStatementNode forStatement, Void source) {
				foreach (var s in forStatement.Initializer) {
					var bounds = s.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						if (s.StatementKind == StatementKind.LocalDeclaration) {
							processor.context.declareLocals((LocalDeclarationStatementNode)s);
						}
					} else {
						return handleStatement(s, null);
					}
				}
				if (forStatement.Condition != null && processor.containsOffset(forStatement.Condition)) {
					return processor.expressionProcessor.handleExpression(forStatement.Condition, null, true);
				}
				foreach (var s in forStatement.Iterator) {
					var bounds = s.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleStatement(s, null);
				}
				if (processor.containsOffset(forStatement.Statement)) {
					return handleStatement(forStatement.Statement, null);
				}

				Environment.trace(this, "for");
				return processor.computeCompletionProposalsInStatement(forStatement);
			}

			protected override ICompletionProposal[] handleForeach(ForeachStatementNode foreachStatement, Void source) {
				if (foreachStatement.Type != null && processor.containsOffset(foreachStatement.Type)) {
					var info = foreachStatement.getUserData(typeof(MemberInfo));
					return processor.computeCompletionProposalsInType(foreachStatement.Type, info.Type);
				}
				if (processor.containsOffset(foreachStatement.Source)) {
					return processor.expressionProcessor.handleExpression(foreachStatement.Source, null, true);
				}
				if (processor.containsOffset(foreachStatement.Statement)) {
					processor.context.declareLocal(foreachStatement);
					return handleStatement(foreachStatement.Statement, null);
				}

				Environment.trace(this, "foreach");
				return processor.computeCompletionProposalsInStatement(foreachStatement);
			}

			protected override ICompletionProposal[] handleGoto(GotoStatementNode gotoStatement, Void source) {
				Environment.trace(this, "goto");
				return processor.computeCompletionProposalsInStatement(gotoStatement);
			}

			protected override ICompletionProposal[] handleGotoCase(GotoCaseStatementNode gotoCase, Void source) {
				// TODO
				Environment.trace(this, "goto case");
				return EMPTY_PROPOSALS;
			}

			protected override ICompletionProposal[] handleIf(IfStatementNode ifStatement, Void source) {
				if (processor.containsOffset(ifStatement.Condition)) {
					return processor.expressionProcessor.handleExpression(ifStatement.Condition, null, true);
				}
				if (processor.containsOffset(ifStatement.IfTrue)) {
					return handleStatement(ifStatement.IfTrue, null);
				}
				if (ifStatement.IfFalse != null && processor.containsOffset(ifStatement.IfFalse)) {
					return handleStatement(ifStatement.IfFalse, null);
				}

				Environment.trace(this, "if");
				return processor.computeCompletionProposalsInStatement(ifStatement);
			}

			protected override ICompletionProposal[] handleLabeled(LabeledStatementNode labeled, Void source) {
				if (processor.containsOffset(labeled.Statement)) {
					return handleStatement(labeled.Statement, null);
				}

				Environment.trace(this, "labeled");
				return processor.computeCompletionProposalsInStatement(labeled);
			}

			protected override ICompletionProposal[] handleLocalDeclaration(LocalDeclarationStatementNode localDeclaration, Void source) {
				if (localDeclaration.Type != null && processor.containsOffset(localDeclaration.Type)) {
					var info = localDeclaration.getUserData(typeof(ExpressionInfo));
					return processor.computeCompletionProposalsInType(localDeclaration.Type, info.Type);
				}
				foreach (var decl in localDeclaration.Declarators) {
					if (decl.Value != null && processor.containsOffset(decl.Value)) {
						return processor.expressionProcessor.handleExpression(decl.Value, null, true);
					}
				}

				Environment.trace(this, "local declaration");
				return processor.computeCompletionProposalsInStatement(localDeclaration);
			}

			protected override ICompletionProposal[] handleReturn(ReturnStatementNode returnStatement, Void source) {
				if (returnStatement.Value != null && processor.containsOffset(returnStatement.Value)) {
					return processor.expressionProcessor.handleExpression(returnStatement.Value, null, false);
				}

				Environment.trace(this, "return");
				var bounds = returnStatement.getUserData(typeof(SyntaxNodeBounds));
				var startToken = bounds.StartToken;
				if (processor.offset > startToken.offset + startToken.length && processor.offset < returnStatement.EndPosition) {
					return processor.computeCompletionProposalsInExpression(returnStatement);
				}
				return processor.computeCompletionProposalsInStatement(returnStatement);
			}

			protected override ICompletionProposal[] handleSwitch(SwitchStatementNode switchStatement, Void source) {
				if (processor.containsOffset(switchStatement.Selector)) {
					return processor.expressionProcessor.handleExpression(switchStatement.Selector, null, true);
				}
				foreach (var section in switchStatement.Sections) {
					var bounds = section.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					foreach (var s in section.Statements) {
						if (processor.containsOffset(s)) {
							return handleStatement(s, null);
						}
						if (s.StatementKind == StatementKind.LocalDeclaration) {
							processor.context.declareLocals((LocalDeclarationStatementNode)s);
						}
					}
				}

				Environment.trace(this, "switch");
				return processor.computeCompletionProposalsInStatement(switchStatement);
			}

			protected override ICompletionProposal[] handleSynchronized(SynchronizedStatementNode synchronizedStatement, Void source) {
				if (processor.containsOffset(synchronizedStatement.Lock)) {
					return processor.expressionProcessor.handleExpression(synchronizedStatement.Lock, null, true);
				}
				if (processor.containsOffset(synchronizedStatement.Statement)) {
					return handleStatement(synchronizedStatement.Statement, null);
				}

				Environment.trace(this, "synchronized");
				return processor.computeCompletionProposalsInStatement(synchronizedStatement);
			}

			protected override ICompletionProposal[] handleThrow(ThrowStatementNode throwStatement, Void source) {
				if (throwStatement.Exception != null && processor.containsOffset(throwStatement.Exception)) {
					return processor.expressionProcessor.handleExpression(throwStatement.Exception, null, true);
				}

				Environment.trace(this, "throw");
				return processor.computeCompletionProposalsInStatement(throwStatement);
			}

			protected override ICompletionProposal[] handleTry(TryStatementNode tryStatement, Void source) {
				if (processor.containsOffset(tryStatement.Block)) {
					return handleBlock(tryStatement.Block, null);
				}
				foreach (var cc in tryStatement.CatchClauses) {
					var bounds = cc.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					if (cc.ExceptionType != null && processor.containsOffset(cc.ExceptionType)) {
						processor.context.declareLocal(cc);
						var t = cc.getUserData(typeof(TypeInfo));
						return processor.computeCompletionProposalsInType(cc.ExceptionType, t);
					}
					if (processor.containsOffset(cc.Block)) {
						return handleBlock(cc.Block, null);
					}
				}
				if (tryStatement.Finally != null && processor.containsOffset(tryStatement.Finally)) {
					return handleBlock(tryStatement.Finally, null);
				}

				Environment.trace(this, "try");
				return processor.computeCompletionProposalsInStatement(tryStatement);
			}

			protected override ICompletionProposal[] handleUsing(UsingStatementNode usingStatement, Void source) {
				if (processor.containsOffset(usingStatement.ResourceAcquisition)) {
					return handleStatement(usingStatement.ResourceAcquisition, null);
				}
				if (processor.containsOffset(usingStatement.Statement)) {
					if (usingStatement.ResourceAcquisition.StatementKind == StatementKind.LocalDeclaration) {
						processor.context.declareLocals((LocalDeclarationStatementNode)usingStatement.ResourceAcquisition);
					}
					return handleStatement(usingStatement.Statement, null);
				}

				Environment.trace(this, "using");
				return processor.computeCompletionProposalsInStatement(usingStatement);
			}

			protected override ICompletionProposal[] handleWhile(WhileStatementNode whileStatement, Void source) {
				if (processor.containsOffset(whileStatement.Condition)) {
					return processor.expressionProcessor.handleExpression(whileStatement.Condition, null, true);
				}
				if (processor.containsOffset(whileStatement.Statement)) {
					return handleStatement(whileStatement.Statement, null);
				}

				Environment.trace(this, "while");
				return processor.computeCompletionProposalsInStatement(whileStatement);
			}

			protected override ICompletionProposal[] handleYield(YieldStatementNode yield, Void source) {
				if (yield.Value != null && processor.containsOffset(yield.Value)) {
					return processor.expressionProcessor.handleExpression(yield.Value, null, false);
				}

				Environment.trace(this, "yield");
				var bounds = yield.getUserData(typeof(SyntaxNodeBounds));
				var startToken = bounds.StartToken;
				// TODO: skip return or break
				if (processor.offset > startToken.offset + startToken.length && processor.offset < yield.EndPosition) {
					return processor.computeCompletionProposalsInExpression(yield);
				}
				return processor.computeCompletionProposalsInStatement(yield);
			}
		}

		private class ExpressionProcessor : ExpressionHandler<Void, ICompletionProposal[]> {
			private ContentAssistProcessor processor;

			ExpressionProcessor(ContentAssistProcessor processor)
					: super(false) {
				this.processor = processor;
			}

			protected override ICompletionProposal[] handleAnonymousObjectCreation(AnonymousObjectCreationExpressionNode anonymousObject,
					Void source, bool nested) {
				foreach (var mi in anonymousObject.MemberDeclarators) {
					var bounds = mi.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					if (processor.containsOffset(mi.Value)) {
						return handleExpression(mi.Value, source, true);
					}

					Environment.trace(this, "member declarator");
					return EMPTY_PROPOSALS;
				}

				Environment.trace(this, "anonymous object");
				return processor.computeCompletionProposalsInExpression(anonymousObject);
			}

			protected override ICompletionProposal[] handleArrayCreation(ArrayCreationExpressionNode arrayCreation, Void source, bool nested) {
				if (arrayCreation.Type != null && processor.containsOffset(arrayCreation.Type)) {
					var info = arrayCreation.getUserData(typeof(ExpressionInfo));
					return processor.computeCompletionProposalsInType(arrayCreation.Type, info.Type);
				}
				foreach (var e in arrayCreation.DimensionExpressions) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}
				if (arrayCreation.Initializer != null && processor.containsOffset(arrayCreation.Initializer)) {
					return handleExpression(arrayCreation.Initializer, null, true);
				}

				Environment.trace(this, "array creation");
				return processor.computeCompletionProposalsInExpression(arrayCreation);
			}

			protected override ICompletionProposal[] handleArrayInitializer(ArrayInitializerExpressionNode arrayInitializer, Void source,
					bool nested) {
				foreach (var e in arrayInitializer.Values) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}

				Environment.trace(this, "array initializer");
				return processor.computeCompletionProposalsInExpression(arrayInitializer);
			}

			protected override ICompletionProposal[] handleAssign(AssignExpressionNode assign, Void source, bool nested) {
				if (processor.containsOffset(assign.Left)) {
					return handleExpression(assign.Left, null, true);
				}
				if (processor.containsOffset(assign.Right)) {
					return handleExpression(assign.Right, null, true);
				}

				Environment.trace(this, "assign");
				return processor.computeCompletionProposalsInExpression(assign);
			}

			protected override ICompletionProposal[] handleBinary(BinaryExpressionNode binary, Void source, bool nested) {
				if (processor.containsOffset(binary.LeftOperand)) {
					return handleExpression(binary.LeftOperand, null, true);
				}
				if (processor.containsOffset(binary.RightOperand)) {
					return handleExpression(binary.RightOperand, null, true);
				}

				Environment.trace(this, "binary");
				return processor.computeCompletionProposalsInExpression(binary);
			}

			protected override ICompletionProposal[] handleCast(CastExpressionNode cast, Void source, bool nested) {
				if (processor.containsOffset(cast.TargetType)) {
				var info = cast.getUserData(typeof(ExpressionInfo));
					return processor.computeCompletionProposalsInType(cast.TargetType, info.Type);
				}
				if (processor.containsOffset(cast.Expression)) {
					return handleExpression(cast.Expression, null, true);
				}

				Environment.trace(this, "cast");
				return processor.computeCompletionProposalsInExpression(cast);
			}

			protected override ICompletionProposal[] handleConditional(ConditionalExpressionNode conditional, Void source, bool nested) {
				if (processor.containsOffset(conditional.Condition)) {
					return handleExpression(conditional.Condition, null, true);
				}
				if (processor.containsOffset(conditional.IfTrue)) {
					return handleExpression(conditional.IfTrue, null, true);
				}
				if (processor.containsOffset(conditional.IfFalse)) {
					return handleExpression(conditional.IfFalse, null, true);
				}

				Environment.trace(this, "conditional");
				return processor.computeCompletionProposalsInExpression(conditional);
			}

			protected override ICompletionProposal[] handleElementAccess(ElementAccessExpressionNode elementAccess, Void source, bool nested) {
				if (processor.containsOffset(elementAccess.TargetObject)) {
					return handleExpression(elementAccess.TargetObject, null, true);
				}
				foreach (var e in elementAccess.Indexes) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}

				Environment.trace(this, "element access");
				return processor.computeCompletionProposalsInExpression(elementAccess);
			}

			protected override ICompletionProposal[] handleInvocation(InvocationExpressionNode invocation, Void source, bool nested) {
				if (processor.containsOffset(invocation.TargetObject)) {
					return handleExpression(invocation.TargetObject, null, true);
				}
				foreach (var e in invocation.Arguments) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}

				Environment.trace(this, "invocation");
				return processor.computeCompletionProposalsInExpression(invocation);
			}

			protected override ICompletionProposal[] handleLambda(LambdaExpressionNode lambda, Void source, bool nested) {
				var m = lambda.getUserData(typeof(MethodInfo));
				var pit = m.Parameters.iterator();
				foreach (var p in lambda.Parameters) {
					var pt = pit.next().Type;

					var bounds = p.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}

					if (p.Type != null && processor.containsOffset(p.Type)) {
						return processor.computeCompletionProposalsInType(p.Type, pt);
					}

					Environment.trace(this, "lambda parameter");
					return EMPTY_PROPOSALS;
				}

				if (processor.containsOffset(lambda.Body)) {
		            processor.context.enterLambda(lambda);
					return processor.statementProcessor.handleStatement(lambda.Body, null);
				}

				Environment.trace(this, "lambda");
				return EMPTY_PROPOSALS;
			}

			protected override ICompletionProposal[] handleLiteral(LiteralExpressionNode literal, Void source, bool nested) {
				Environment.trace(this, "literal");
				return processor.computeCompletionProposalsInExpression(literal);
			}

			protected override ICompletionProposal[] handleMemberAccess(MemberAccessExpressionNode memberAccess, Void source, bool nested) {
				if (processor.containsOffset(memberAccess.TargetObject)) {
					return handleExpression(memberAccess.TargetObject, null, true);
				}
				if (processor.containsOffset(memberAccess.Member)) {
					Environment.trace(this, "member access name");
					int index = Highlighter.getPositionIndex(processor.tokens, processor.offset);
					var token = processor.tokens[index];
					if (token.offset == processor.offset) {
						token = processor.tokens[index - 1];
					}
					var length = token.length - (processor.offset - token.offset);
					var prefix = new String(processor.text, token.offset, processor.offset - token.offset);
					var tinfo = memberAccess.TargetObject.getUserData(typeof(ExpressionInfo));
					return CompletionProposalHelper.createCompletionProposals(processor.offset, length, prefix, Query.empty<String>(),
							processor.context.getMembers(tinfo.Type, tinfo.Member != null && tinfo.Member.MemberKind == MemberKind.Type),
							Query.empty<String>());
				}

				Environment.trace(this, "member access");
				var token = processor.getPreviousToken(processor.offset);
				if (token.LexicalUnit == LexicalUnit.Dot) {
					if (processor.inEditedText) {
						return processor.computeCompletionProposalsInExpression(memberAccess.TargetObject);
					} else {
						var info = memberAccess.getUserData(typeof(ExpressionInfo));
						var member = info.Member;
						if (member == null) {
							var type = info.Type;
							if (type == null) {
								// Package
							} else {
								return CompletionProposalHelper.createCompletionProposals(processor.offset, 0, "", Query.empty<String>(),
										processor.context.getMembers(type, true), Query.empty<String>());
							}
						} else {
							var tinfo = memberAccess.TargetObject.getUserData(typeof(ExpressionInfo));
							return CompletionProposalHelper.createCompletionProposals(processor.offset, 0, "", Query.empty<String>(),
									processor.context.getMembers(tinfo.Type, tinfo.Member != null && tinfo.Member.MemberKind == MemberKind.Type),
									Query.empty<String>());
						}
					}
				}
				return EMPTY_PROPOSALS;
			}

			protected override ICompletionProposal[] handleObjectCreation(ObjectCreationExpressionNode objectCreation, Void source, bool nested) {
				if (processor.containsOffset(objectCreation.Type)) {
					var info = objectCreation.getUserData(typeof(ExpressionInfo));
					return processor.computeCompletionProposalsInType(objectCreation.Type, info.Type);
				}
				foreach (var e in objectCreation.Arguments) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}
				if (objectCreation.Initializer != null && processor.containsOffset(objectCreation.Initializer)) {
					return handleExpression(objectCreation.Initializer, null, true);
				}

				Environment.trace(this, "object creation");
				return processor.computeCompletionProposalsInExpression(objectCreation);
			}

			protected override ICompletionProposal[] handleCollectionInitializer(CollectionInitializerExpressionNode initializer, Void source,
					bool nested) {
				foreach (var e in initializer.Values.selectMany(p => p)) {
					var bounds = e.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					return handleExpression(e, source, true);
				}

				Environment.trace(this, "collection initializer");
				return processor.computeCompletionProposalsInExpression(initializer);
			}

			// TODO: handleQuery

			protected override ICompletionProposal[] handleObjectInitializer(ObjectInitializerExpressionNode initializer, Void source,
					bool nested) {
				foreach (var init in initializer.getMemberInitializers()) {
					var bounds = init.getUserData(typeof(SyntaxNodeBounds));
					if (bounds == null || bounds.isAfterOffset(processor.offset)) {
						break;
					}
					if (bounds.isBeforeOffset(processor.offset)) {
						continue;
					}
					if (processor.containsOffset(init.Value)) {
						return handleExpression(init.Value, null, true);
					}

					Environment.trace(this, "object member initializer");
					return processor.computeCompletionProposalsInExpression(initializer);
				}

				Environment.trace(this, "object initializer");
				return processor.computeCompletionProposalsInExpression(initializer);
			}

			protected override ICompletionProposal[] handleSimpleName(SimpleNameExpressionNode simpleName, Void source, bool nested) {
				Environment.trace(this, "simple name");
				return processor.computeCompletionProposalsInExpression(simpleName);
			}

			protected override ICompletionProposal[] handleSizeof(SizeofExpressionNode sizeofExpression, Void source, bool nested) {
				if (processor.containsOffset(sizeofExpression.Expression)) {
					return handleExpression(sizeofExpression.Expression, null, true);
				}
				Environment.trace(this, "sizeof");
				return processor.computeCompletionProposalsInExpression(sizeofExpression);
			}

			protected override ICompletionProposal[] handleSuperAccess(SuperAccessExpressionNode superAccess, Void source, bool nested) {
				Environment.trace(this, "super access");
				return processor.computeCompletionProposalsInExpression(superAccess);
			}

			protected override ICompletionProposal[] handleThisAccess(ThisAccessExpressionNode thisAccess, Void source, bool nested) {
				Environment.trace(this, "this access");
				return processor.computeCompletionProposalsInExpression(thisAccess);
			}

			protected override ICompletionProposal[] handleType(TypeExpressionNode type, Void source, bool nested) {
				var info = type.getUserData(typeof(ExpressionInfo));
				return processor.computeCompletionProposalsInType(type.TypeReference, info.Type);
			}

			protected override ICompletionProposal[] handleTypeof(TypeofExpressionNode typeofExpression, Void source, bool nested) {
				if (processor.containsOffset(typeofExpression.Type)) {
					return processor.computeCompletionProposalsInType(typeofExpression.Type, typeofExpression.getUserData(typeof(TypeInfo)));
				}

				Environment.trace(this, "typeof");
				if (!processor.inEditedText) {
					var token = processor.getPreviousToken(processor.offset);
					if (token != null && token.LexicalUnit == LexicalUnit.OpenParenthesis) {
						return CompletionProposalHelper.createCompletionProposals(processor.offset, 0, "", processor.context.getRootPackages(),
								processor.context.getTypeMembers(), TYPE_TEXTS);
					}
				}
				return processor.computeCompletionProposalsInExpression(typeofExpression);
			}

			protected override ICompletionProposal[] handleUnary(UnaryExpressionNode unary, Void source, bool nested) {
				if (processor.containsOffset(unary.Operand)) {
					return handleExpression(unary.Operand, null, true);
				}

				Environment.trace(this, "unary");
				return processor.computeCompletionProposalsInExpression(unary);
			}
		}
	}
}


text:
URL=http://pencil.org/

init:
	pip install -r requirements.txt

parse:
	python openparser/parse.py $(URL)

test:
	pytest tests

.PHONY: init test


text:
package org.innovateuk.ifs.testdata.builders;

import org.innovateuk.ifs.application.resource.ApplicationResource;
import org.innovateuk.ifs.competition.resource.CompetitionResource;
import org.innovateuk.ifs.file.domain.FileEntry;
import org.innovateuk.ifs.finance.domain.ApplicationFinance;
import org.innovateuk.ifs.finance.resource.ApplicationFinanceResource;
import org.innovateuk.ifs.finance.resource.EmployeesAndTurnoverResource;
import org.innovateuk.ifs.finance.resource.GrowthTableResource;
import org.innovateuk.ifs.finance.resource.OrganisationSize;
import org.innovateuk.ifs.finance.resource.category.FinanceRowCostCategory;
import org.innovateuk.ifs.finance.resource.category.LabourCostCategory;
import org.innovateuk.ifs.finance.resource.category.OtherFundingCostCategory;
import org.innovateuk.ifs.finance.resource.cost.*;
import org.innovateuk.ifs.organisation.resource.OrganisationResource;
import org.innovateuk.ifs.organisation.resource.OrganisationTypeEnum;
import org.innovateuk.ifs.testdata.builders.data.IndustrialCostData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import static java.util.Collections.emptyList;
import static org.innovateuk.ifs.finance.builder.EquipmentCostBuilder.newEquipment;
import static org.innovateuk.ifs.finance.builder.LabourCostBuilder.newLabourCost;
import static org.innovateuk.ifs.finance.builder.MaterialsCostBuilder.newMaterials;
import static org.innovateuk.ifs.finance.resource.cost.OverheadRateType.HORIZON_EUROPE_GUARANTEE_TOTAL;

/**
 * Generates Indisutrial Finances for an Organisation on an Application
 */
public class IndustrialCostDataBuilder extends BaseDataBuilder<IndustrialCostData, IndustrialCostDataBuilder> {

    private static final Logger LOG = LoggerFactory.getLogger(IndustrialCostDataBuilder.class);

    public IndustrialCostDataBuilder withApplicationFinance(ApplicationFinanceResource applicationFinance) {
        return with(data -> data.setApplicationFinance(applicationFinance));
    }

    public IndustrialCostDataBuilder withCompetition(CompetitionResource competitionResource) {
        return with(data -> data.setCompetition(competitionResource));
    }

    public IndustrialCostDataBuilder withOrganisation(OrganisationResource organisation) {
        return with(data -> data.setOrganisation(organisation));
    }

    public IndustrialCostDataBuilder withWorkingDaysPerYear(Integer workingDays) {
        return updateCostCategory(LabourCostCategory.class, FinanceRowType.LABOUR,
                labourCostCategory -> {
                    LabourCost workingDaysCost = labourCostCategory.getWorkingDaysPerYearCostItem();
                    workingDaysCost.setLabourDays(workingDays);
                    financeRowCostsService.update(workingDaysCost.getId(), workingDaysCost);
                });
    }

    public IndustrialCostDataBuilder withOtherFunding(String fundingSource, LocalDate dateSecured, BigDecimal fundingAmount) {
        return updateCostCategory(OtherFundingCostCategory.class, FinanceRowType.OTHER_FUNDING,
                otherFundingCostCategory -> {
                    BaseOtherFunding otherFunding = otherFundingCostCategory.getOtherFunding();
                    otherFunding.setOtherPublicFunding("Yes");
                    financeRowCostsService.update(otherFunding.getId(), otherFunding);
                }).addCostItem("Other funding", (finance) -> {
            OtherFunding otherFunding = new OtherFunding(finance.getId());
            otherFunding.setFundingAmount(fundingAmount);
            otherFunding.setFundingSource(fundingSource);
            otherFunding.setSecuredDate(dateSecured.format(DateTimeFormatter.ofPattern("MM-yyyy")));
            return otherFunding;
        });
    }

    public IndustrialCostDataBuilder withGrantClaim(BigDecimal grantClaim) {
        return updateCostItem(GrantClaimPercentage.class, FinanceRowType.FINANCE, existingCost -> {
            existingCost.setPercentage(grantClaim);
            financeRowCostsService.update(existingCost.getId(), existingCost);
        }, costNotApplicableForKtpPartner());
    }

    private Predicate<IndustrialCostData> costNotApplicableForKtpPartner() {
        return data -> !data.getCompetition().isKtp() || data.getOrganisation().getOrganisationTypeEnum() == OrganisationTypeEnum.KNOWLEDGE_BASE;
    }

    public IndustrialCostDataBuilder withLabourEntry(String role, Integer annualSalary, Integer daysToBeSpent) {
        return addCostItem("Labour", (finance) ->
                newLabourCost()
                        .withId()
                        .withName()
                        .withRole(role)
                        .withGrossEmployeeCost(bd(annualSalary))
                        .withLabourDays(daysToBeSpent)
                        .withDescription()
                        .withTargetId(finance.getId())
                        .build());
    }

    public IndustrialCostDataBuilder withMaterials(String item, BigDecimal cost, Integer quantity) {
        return addCostItem("Materials", (finance) ->
                newMaterials()
                        .withId()
                        .withItem(item)
                        .withCost(cost)
                        .withQuantity(quantity)
                        .withTargetId(finance.getId())
                        .build());
    }

    public IndustrialCostDataBuilder withEquipment(String item, BigDecimal cost, Integer quantity) {
        return addCostItem("Equipment", (finance) ->
                newEquipment()
                        .withId()
                        .withItem(item)
                        .withCost(cost)
                        .withQuantity(quantity)
                        .withTargetId(finance.getId())
                        .build());
    }

    public IndustrialCostDataBuilder withCapitalUsage(Integer depreciation, String description, boolean existing,
                                                      BigDecimal presentValue, BigDecimal residualValue,
                                                      Integer utilisation) {
        return addCostItem("Capital Usage", (finance) ->
                new CapitalUsage(null, depreciation, description, existing ? "Existing" : "New", presentValue, residualValue, utilisation, finance.getId()));
    }

    public IndustrialCostDataBuilder withOtherGoods(Integer depreciation, String description, boolean existing,
                                                      BigDecimal presentValue, BigDecimal residualValue,
                                                      Integer utilisation) {
        return addCostItem("Other Goods", (finance) ->
                new OtherGoods(null, depreciation, description, existing ? "Existing" : "New", presentValue, residualValue, utilisation, finance.getId()));
    }

    public IndustrialCostDataBuilder withSubcontractingCost(String name, String country, String role, BigDecimal cost) {
        return addCostItem("Sub-contracting costs", (finance) ->
                new SubContractingCost(null, cost, country, name, role, finance.getId()));
    }

    public IndustrialCostDataBuilder withTravelAndSubsistence(String purpose, Integer numberOfTimes, BigDecimal costEach) {
        return addCostItem("Travel and subsistence", (finance) ->
                new TravelCost(null, purpose, costEach, numberOfTimes, finance.getId()));
    }

    public IndustrialCostDataBuilder withOtherCosts(String description, BigDecimal estimatedCost) {
        return addCostItem("Other costs", (finance) ->
                new OtherCost(null, description, estimatedCost, finance.getId()),
                costNotApplicableForKtpPartner());
    }

    public IndustrialCostDataBuilder withOrganisationSize(OrganisationSize organsationSize) {
        return with(data -> {

            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();

            applicationFinance.setOrganisationSize(organsationSize);

            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withProjectGrowthTable(YearMonth financialYearEnd,
                                                            long headCountAtLastFinancialYear,
                                                            BigDecimal annualTurnoverAtLastFinancialYear,
                                                            BigDecimal annualProfitsAtLastFinancialYear,
                                                            BigDecimal annualExportAtLastFinancialYear,
                                                            BigDecimal researchAndDevelopmentSpendAtLastFinancialYear) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();

            GrowthTableResource growthTable = new GrowthTableResource();
            growthTable.setFinancialYearEnd(financialYearEnd.atEndOfMonth());
            growthTable.setEmployees(headCountAtLastFinancialYear);
            growthTable.setAnnualTurnover(annualTurnoverAtLastFinancialYear);
            growthTable.setAnnualProfits(annualProfitsAtLastFinancialYear);
            growthTable.setAnnualExport(annualExportAtLastFinancialYear);
            growthTable.setResearchAndDevelopment(researchAndDevelopmentSpendAtLastFinancialYear);

            applicationFinance.setFinancialYearAccounts(growthTable);

            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withEmployeesAndTurnover(long employees, BigDecimal turnover) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();

            EmployeesAndTurnoverResource employeesAndTurnoverResource = new EmployeesAndTurnoverResource();
            employeesAndTurnoverResource.setTurnover(turnover);
            employeesAndTurnoverResource.setEmployees(employees);

            applicationFinance.setFinancialYearAccounts(employeesAndTurnoverResource);
            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }
    public IndustrialCostDataBuilder withWorkPostcode(String workPostcode) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();

            applicationFinance.setWorkPostcode(workPostcode);

            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }
    public IndustrialCostDataBuilder withNorthernIrelandDeclaration(boolean northernIrelandDeclaration) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();

            applicationFinance.setNorthernIrelandDeclaration(northernIrelandDeclaration);

            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withLocation() {
        return with(data -> {

            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();
            OrganisationResource org = organisationService.findById(applicationFinance.getOrganisation()).getSuccess();

            if (org.isInternational()) {
                applicationFinance.setInternationalLocation("France");
            } else {
                applicationFinance.setWorkPostcode("AB12 3CD");
            }

            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withAdministrationSupportCostsNone() {
        return doSetAdministrativeSupportCosts(OverheadRateType.NONE, OverheadRateType.NONE.getRate());
    }

    public IndustrialCostDataBuilder withHecpAdministrationSupportCostsNone() {
        return doSetAdministrativeSupportCostsHecp(HORIZON_EUROPE_GUARANTEE_TOTAL, HORIZON_EUROPE_GUARANTEE_TOTAL.getRate());
    }

    public IndustrialCostDataBuilder withAdministrationSupportCostsDefaultRate() {
        return doSetAdministrativeSupportCosts(OverheadRateType.DEFAULT_PERCENTAGE, OverheadRateType.DEFAULT_PERCENTAGE.getRate());
    }

    public IndustrialCostDataBuilder withHecpAdministrationSupportCostsDefaultRate() {
        return doSetAdministrativeSupportCostsHecp(HORIZON_EUROPE_GUARANTEE_TOTAL, HORIZON_EUROPE_GUARANTEE_TOTAL.getRate());
    }

    public IndustrialCostDataBuilder withAdministrationSupportCostsTotalRate(Integer customRate) {
        return doSetAdministrativeSupportCosts(OverheadRateType.TOTAL, customRate);
    }

    public IndustrialCostDataBuilder withHecpAdministrationSupportCostsTotalRate(Integer customRate) {
        return doSetAdministrativeSupportCostsHecp(HORIZON_EUROPE_GUARANTEE_TOTAL, customRate);
    }

    public IndustrialCostDataBuilder withProcurementOverheads(String item, int project, int company) {
        return addCostItem("Procurement overhead", (finance) ->
                new ProcurementOverhead(null, item, BigDecimal.valueOf(project), company, finance.getId()));
    }

    public IndustrialCostDataBuilder withGrantClaimAmount(int amount) {
        return updateCostItem(GrantClaimAmount.class, FinanceRowType.GRANT_CLAIM_AMOUNT, existingCost -> {
            existingCost.setAmount(BigDecimal.valueOf(amount));
            financeRowCostsService.update(existingCost.getId(), existingCost);
        });
    }

    public IndustrialCostDataBuilder withVat(boolean registered) {
        return updateCostItem(Vat.class, FinanceRowType.VAT, existingCost -> {
            existingCost.setRegistered(registered);
            financeRowCostsService.update(existingCost.getId(), existingCost);
        });
    }

    public IndustrialCostDataBuilder withAssociateSalaryCosts(String role, Integer duration, BigInteger cost) {
        return addCostItem("Associate Salary Costs", (finance) ->
                new AssociateSalaryCost(finance.getId(), null, role, duration, cost));
    }

    public IndustrialCostDataBuilder withAssociateDevelopmentCosts(String role, Integer duration, BigInteger cost) {
        return addCostItem("Associate Development Costs", (finance) ->
                new AssociateDevelopmentCost(finance.getId(), null, role, duration, cost));
    }

    public IndustrialCostDataBuilder withConsumables(String item, BigInteger cost, Integer quantity) {
        return addCostItem("Consumables", (finance) ->
                new Consumable(null, item, cost, quantity, finance.getId()));
    }

    public IndustrialCostDataBuilder withAssociateSupport(String description, BigInteger cost) {
        return addCostItem("Associate Support Costs", (finance) ->
                new AssociateSupportCost(finance.getId(), null, description, cost));
    }

    public IndustrialCostDataBuilder withKnowledgeBase(String description, BigInteger cost) {
        return addCostItem("Associate Support Costs", (finance) ->
                new KnowledgeBaseCost(finance.getId(), null, description, cost));
    }

    public IndustrialCostDataBuilder withEstateCosts(String description, BigInteger cost) {
        return addCostItem("Estate Costs", (finance) ->
                new EstateCost(finance.getId(), null, description, cost));
    }

    public IndustrialCostDataBuilder withKtpTravel(KtpTravelCost.KtpTravelCostType type, String description, BigDecimal cost, Integer quantity) {
        return addCostItem("KTP Travel", (finance) ->
                new KtpTravelCost(null, type, description, cost, quantity, finance.getId()));
    }

    public IndustrialCostDataBuilder withAdditionalCompanyCosts(AdditionalCompanyCost.AdditionalCompanyCostType type, String description, BigInteger cost) {
        return addCostItem("Additional Company Costs", (finance) ->
                new AdditionalCompanyCost(finance.getId(), null, type, description, cost));
    }

    public IndustrialCostDataBuilder withPreviousFunding(String otherPublicFunding, String fundingSource, String securedDate, BigDecimal fundingAmount) {
        return addCostItem("Previous Funding", (finance) ->
                new PreviousFunding(null, otherPublicFunding, fundingSource, securedDate, fundingAmount, finance.getId()));
    }

    private IndustrialCostDataBuilder doSetAdministrativeSupportCosts(OverheadRateType rateType, Integer rate) {
        return updateCostItem(Overhead.class, FinanceRowType.OVERHEADS, existingCost -> {
            Overhead updated = new Overhead(existingCost.getId(), rateType, rate, existingCost.getTargetId());
            financeRowCostsService.update(existingCost.getId(), updated);
        });
    }

    private IndustrialCostDataBuilder doSetAdministrativeSupportCostsHecp(OverheadRateType rateType, Integer rate) {
        return updateCostItem(HecpIndirectCosts.class, FinanceRowType.HECP_INDIRECT_COSTS, existingCost -> {
            HecpIndirectCosts updated = new HecpIndirectCosts(existingCost.getId(), rateType, rate, existingCost.getTargetId());
            financeRowCostsService.update(existingCost.getId(), updated);
        });
    }

    public IndustrialCostDataBuilder withAcademicAndSecretarialSupport(BigInteger cost) {
        return addCostItem("Academic And Secretarial Support", (finance) ->
                new AcademicAndSecretarialSupport(finance.getId(), null, cost));
    }

    public IndustrialCostDataBuilder withIndirectCosts(BigInteger cost) {
        return addCostItem("Indirect costs", (finance) ->
                new IndirectCost(finance.getId(), null, cost));
    }

    private <T extends FinanceRowItem> IndustrialCostDataBuilder updateCostItem(Class<T> clazz, FinanceRowType financeRowType, Consumer<T> updateFn, Predicate<IndustrialCostData> predicate) {
        return with(data -> {
            if (predicate.test(data)) {
                List<FinanceRowItem> rows = data.getApplicationFinance().getFinanceOrganisationDetails().get(financeRowType).getCosts();
                rows.forEach(item -> updateFn.accept((T) item));
            }
        });
    }
    private <T extends FinanceRowItem> IndustrialCostDataBuilder updateCostItem(Class<T> clazz, FinanceRowType financeRowType, Consumer<T> updateFn) {
        return updateCostItem(clazz, financeRowType, updateFn, (x) -> true);
    }

    private <C extends FinanceRowCostCategory> IndustrialCostDataBuilder updateCostCategory(Class<C> clazz, FinanceRowType financeRowType, Consumer<C> updateFn) {
        return with(data -> {
            C category = (C) data.getApplicationFinance().getFinanceOrganisationDetails().get(financeRowType);
            updateFn.accept(category);
        });
    }

    private IndustrialCostDataBuilder addCostItem(String financeRowName, Function<ApplicationFinanceResource, FinanceRowItem> cost) {
        return addCostItem(financeRowName, cost, data -> true);
    }

    private IndustrialCostDataBuilder addCostItem(String financeRowName, Function<ApplicationFinanceResource, FinanceRowItem> cost, Predicate<IndustrialCostData> predicate) {
        return with(data -> {
            if (predicate.test(data)) {

                FinanceRowItem newCostItem = cost.apply(data.getApplicationFinance());

                financeRowCostsService.create(newCostItem.getTargetId(), newCostItem).
                        getSuccess();
            }
        });
    }

    public IndustrialCostDataBuilder withFecEnabled(Boolean enabled) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();
            applicationFinance.setFecModelEnabled(enabled);
            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withFecCertExpiryDate(LocalDate fecCertExpiryDate) {
        return with(data -> {
            ApplicationFinanceResource applicationFinance =
                    financeService.getApplicationFinanceById(data.getApplicationFinance().getId()).
                            getSuccess();
            applicationFinance.setFecCertExpiryDate(fecCertExpiryDate);
            financeService.updateApplicationFinance(applicationFinance.getId(), applicationFinance);
        });
    }

    public IndustrialCostDataBuilder withUploadedFecFile() {
        return with(data -> {
            FileEntry fileEntry = fileEntryRepository.save(
                    new FileEntry(null, "fec-file" + data.getApplicationFinance().getId() + ".pdf", "application/pdf", 7945));
            ApplicationFinance finance = applicationFinanceRepository.findById(data.getApplicationFinance().getId()).get();
            finance.setFecFileEntry(fileEntry);
            applicationFinanceRepository.save(finance);
        });
    }

    public static IndustrialCostDataBuilder newIndustrialCostData(ServiceLocator serviceLocator) {
        return new IndustrialCostDataBuilder(emptyList(), serviceLocator);
    }

    private IndustrialCostDataBuilder(List<BiConsumer<Integer, IndustrialCostData>> multiActions,
                                      ServiceLocator serviceLocator) {

        super(multiActions, serviceLocator);
    }

    @Override
    protected IndustrialCostDataBuilder createNewBuilderWithActions(List<BiConsumer<Integer, IndustrialCostData>> actions) {
        return new IndustrialCostDataBuilder(actions, serviceLocator);
    }

    @Override
    protected IndustrialCostData createInitial() {
        return new IndustrialCostData();
    }

    private BigDecimal bd(Integer value) {
        return BigDecimal.valueOf(value);
    }

    @Override
    protected void postProcess(int index, IndustrialCostData instance) {
        super.postProcess(index, instance);
        OrganisationResource organisation = organisationService.findById(instance.getApplicationFinance().getOrganisation()).getSuccess();
        ApplicationResource application = applicationService.getApplicationById(instance.getApplicationFinance().getApplication()).getSuccess();
        LOG.info("Created Industrial Costs for Application '{}', Organisation '{}'", application.getName(), organisation.getName());
    }
}


text: My collection of deep networks


text:
describe('Fiber.Extensions.Access', function() {

  before(function() {
    makeSpyable(this);
  });

  beforeEach(function() {
    this.container = {};
    this.obj = { container: this.container };
    if (Fiber.hasExtension('Access'))
      Fiber.applyExtension('Access', this.obj);
  });

  it('should have `Access` extension', function() {
    expect(Fiber.container.extensions.items).to.have.property('Access');
    expect(Fiber.getExtension('Access')).not.to.be.null;
  });

  it('should `get` property by alias with defaults', function() {
    expect(this.obj.get('container')).to.eql(this.container);
    expect(this.obj.get('notExist')).to.be.undefined;
    expect(this.obj.get('notExist', 'NOT_EXIST')).to.eql('NOT_EXIST');

    this.container.key = true;
    expect(this.obj.get('container.key')).to.be.true;
  });

  it('should `set` property', function() {
    this.obj.set('new', 'NEW');
    expect(this.obj).to.have.property('new');
    expect(this.obj['new']).to.eql('NEW');

    this.obj.set('container.key', 'VALUE');
    expect(this.container).to.have.property('key');
    expect(this.container['key']).to.eql('VALUE');
  });

  it('should check existence (`has`) of given property in object', function() {
    expect(this.obj.has('container')).to.be.true;
    this.container.key = true;
    expect(this.obj.has('container.key')).to.be.true;
    expect(this.obj.has('container.value')).to.be.false;
  });

  it('should return (`result`) value and if the resolved value is a function it's invoked', function() {
    expect(this.obj.result('container')).to.eql(this.container);
    this.container.key = true;
    expect(this.obj.result('container.key')).to.be.true;

    this.container.end = function() { return true };
    expect(this.obj.result('container.end')).to.be.true;
  });

  it('should forget property', function() {
    this.container.key = true;
    this.obj.forget('container.key');
    expect(this.obj.container).to.eql({});

    this.obj.forget('container');
    expect(this.obj.container).to.be.undefined;
  });

  after(function() {
    this.clearSpies();
  });

});