ImmediateBuilder.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package ru.malik.elaborarer.avtoo.compiler;

import avt.io.*;
import avt.util.*;
import ru.malik.elaborarer.avtoo.lang.*;

public class ImmediateBuilder(TableBuilder, AVTOOConstants, AVTOORecompilable, AVTOOService)
{
    private static void requiresValue(Node value) {
        Type type = value.type;
        if(type == null || type.isVoid()) switch(value.instruction)
        {
        case STORE_LOCAL:
        case STORE_STATIC:
            {
                value.type = type = ((TypedItem) value.operand1).type;
                value.parentCode.createAndAppendNode(value).setData(-1, null, DUP1, type);
            }
            break;
        case WRITE_FIELD:
        case WRITE_SPECIAL:
        case WRITE_PROPERTY:
            {
                value.type = type = ((TypedItem) value.operand1).type;
                value.parentCode.createAndAppendNode(value).setData(-1, null, DUP1X1, type);
            }
            break;
        case WRITE_COMPONENT:
            {
                value.type = type = (Type) value.operand1;
                value.parentCode.createAndAppendNode(value).setData(-1, null, DUP1X2, type);
            }
            break;
        case INVOKE_SERVICE:
        case INVOKE_SPECIAL:
        case INVOKE_VIRTUAL:
            Callable callable = (Callable) value.operand1;
            if(callable instanceof Operator && ((Operator) callable).kind == WRITE_COMPONENT)
            {
                value.type = type = callable.arguments[1].type;
                value.parentCode.createAndAppendNode(value).setData(-1, null, DUP1X2, type);
            }
        }
    }

    private static void defineAttainability(byte[] attainability, Code code, int length) {
        for(boolean added = false, int cindex = 0; ; )
        {
            Node node = code[cindex];
            int instruction = node.instruction;
            if(node.persistent && instruction != BEGIN || instruction == METHOD_ENTER || instruction >= EXCEPT_ENTER && instruction <= EXCEPT_LEAVE || attainability[cindex] != 0)
            {
                for(attainability[cindex] = -1, int jindex = node.getJumpCasesLength(); jindex-- > -1; )
                {
                    Node target = jindex < 0 ? node.jumpDefault : node.getJumpCaseNodeAt(jindex);
                    if(target != null)
                    {
                        int order = target.order;
                        if(order >= 0 && attainability[order] == 0)
                        {
                            attainability[order] = -1;
                            added = true;
                        }
                    }
                }
            }
            if(++cindex >= length)
            {
                if(!added) break;
                added = false;
                cindex = 0;
            }
        }
    }

    private static void appendPropertyIndexCode(int position, Node parent, Constant constant, TypedMember member) {
        if(constant != null)
        {
            parent.parentCode.createAndAppendNode(parent).setData(position, constant.type, LOAD_CONST, constant);
            return;
        }
        if(member instanceof Field)
        {
            Code code = parent.parentCode;
            Callable enclosingCallable = code.parentCallable;
            ClassType enclosingClassType = enclosingCallable.parentType;
            Node index = code.createAndAppendNode(parent).setData(position, member.type, READ_FIELD, member);
            code.createAndAppendNode(index).setData(position, enclosingClassType.getRealType(), LOAD_LOCAL, enclosingCallable.arguments.thisArgument);
            return;
        }
        if(member instanceof Method)
        {
            Code code = parent.parentCode;
            Callable enclosingCallable = code.parentCallable;
            ClassType enclosingClassType = enclosingCallable.parentType;
            Node index = code.createAndAppendNode(parent).setData(position, member.type, invokeInstructionFor(member, enclosingClassType), member);
            code.createAndAppendNode(index).setData(position, enclosingClassType.getRealType(), LOAD_LOCAL, enclosingCallable.arguments.thisArgument);
        }
    }

    private static boolean isLogicalConditionNode(Node node) {
        Node subnode = node[1];
        switch(subnode.instruction)
        {
        case BOOL_OR:
        case BOOL_AND:
        case BOOL_NOT:
            return true;
        case BOOL_COND:
            if(isLogicalConditionNode(subnode)) return true;
        }
        switch((subnode = node[-1]).instruction)
        {
        case BOOL_OR:
        case BOOL_AND:
        case BOOL_NOT:
            return true;
        case BOOL_COND:
            return isLogicalConditionNode(subnode);
        }
        return false;
    }

    private static boolean isHandledException(ClassType type, Node parent, Callable callable) {
        for(Node handler = parent; handler != null; handler = handler.parentNode) if(handler.instruction == BEGIN) for(int index = (handler = handler.parentNode).length; index-- > 1; )
        {
            Node node = handler[index];
            if(node.instruction == CATCH && ((ClassType) node.reference1).isAssignableFrom(type)) return true;
        }
        return callable.canThrown(type);
    }

    private static int invokeInstructionFor(Member foundCallable, ClassType foundPlace) {
        return foundCallable.visibility <= PRIVATE || foundCallable.isFinal() || foundPlace.isFinal() || foundCallable.parentType.isHelper() ? (
            INVOKE_SPECIAL
        ) : foundPlace.isService() ? (
            INVOKE_SERVICE
        ) : (
            INVOKE_VIRTUAL
        );
    }

    private static ClassType getUnhandledException(Method method, Node parent, Callable callable) {
        for(int index = method.getThrowablesLength(); index-- > 0; )
        {
            ClassType type = method.getThrowableTypeAt(index);
            if(!type.isFreeThrowableType() && !isHandledException(type, parent, callable)) return type;
        }
        return null;
    }

    private static Node cast(Node value, Type newType) {
        Type oldType = value.type;
        if(newType != oldType)
        {
            if(oldType.isNull())
            {
                if(!newType.isPrimitive())
                {
                    value.type = newType;
                }
            }
            else if(oldType.isPrimitive())
            {
                if(newType.isPrimitive())
                {
                    TableItem operand = value.operand1;
                    if(value.instruction == LOAD_CONST)
                    {
                        value.type = newType;
                        value.operand1 = ((Constant) operand).castTo(newType);
                    }
                    else if(newType.isInt() && !oldType.isStackable())
                    {
                        value.type = newType;
                    }
                    else
                    {
                        newType.makeCompilable();
                        Code code = value.parentCode;
                        Node cast = code.createAndInsertNode(value.parentNode, value.index).setData(-1, newType, CAST_TO, newType, oldType);
                        code.moveNode(value, cast, 0);
                        return cast;
                    }
                }
            }
            else
            {
                if(!newType.isPrimitive())
                {
                    if(newType.isAssignableFrom(oldType))
                    {
                        value.type = newType;
                    }
                    else
                    {
                        newType.makeCompilable();
                        Code code = value.parentCode;
                        Node cast = code.createAndInsertNode(value.parentNode, value.index).setData(-1, newType, CAST_TO, newType, oldType);
                        code.moveNode(value, cast, 0);
                        return cast;
                    }
                }
            }
        }
        return value;
    }

    private Constant fldNull;
    private Constant fldTrue;
    private Constant fldFalse;
    private NullType fldTypeNull;
    private ClassType fldTypeClass;
    private ClassType fldTypeObject;
    private ClassType fldTypeString;
    private ClassType fldTypeStruct;
    private ClassType fldTypePackage;
    private ClassType fldTypeThrowable;
    private PrimitiveType fldTypeVoid;
    private PrimitiveType fldTypeBoolean;
    private PrimitiveType fldTypeInt;
    private PrimitiveType fldTypeLong;
    private ConstantFactory fldConstantFactory;
    private CompilerParallelWorker fldThreadItemHolder;
    private final boolean fldLibrary;
    private final boolean fldStaticFieldsOnly;
    private final ImmediateBuilderItemHolder fldGlobalItemHolder;

    public (int pointerSize): super(pointerSize) {
        fldGlobalItemHolder = new ImmediateBuilderItemHolder();
    }

    public (int pointerSize, boolean staticFieldsOnly): super(pointerSize) {
        fldStaticFieldsOnly = staticFieldsOnly;
        fldGlobalItemHolder = new ImmediateBuilderItemHolder();
    }

    public (int pointerSize, boolean staticFieldsOnly, boolean library): super(pointerSize) {
        fldLibrary = library;
        fldStaticFieldsOnly = staticFieldsOnly;
        fldGlobalItemHolder = new ImmediateBuilderItemHolder();
    }

    public void compile() throws IOException, CompilerException {
        /* -- предыдущие стадии -- */
        super.compile();
        /* -- константы и типы, используемые в следующей стадии -- */
        ConstantFactory factory = getConstantFactory();
        fldNull = factory.createNull();
        fldTrue = factory.createBoolean(true);
        fldFalse = factory.createBoolean(false);
        fldTypeNull = getNullType();
        fldTypeClass = getClassType(PACKNAME_LANG + "." + TYPENAME_CLASS);
        fldTypeObject = getClassType(PACKNAME_LANG + "." + TYPENAME_OBJECT);
        fldTypeString = getClassType(PACKNAME_LANG + "." + TYPENAME_STRING);
        fldTypeStruct = getClassType(PACKNAME_LANG + "." + TYPENAME_STRUCT);
        fldTypePackage = getClassType(PACKNAME_LANG + "." + TYPENAME_PACKAGE);
        fldTypeThrowable = getClassType(PACKNAME_LANG + "." + TYPENAME_THROWABLE);
        fldTypeVoid = getPrimitiveType(VOID);
        fldTypeBoolean = getPrimitiveType(BOOLEAN);
        fldTypeInt = getPrimitiveType(INT);
        fldTypeLong = getPrimitiveType(LONG);
        fldConstantFactory = factory;
        /* 6. Стадия построения исполняемого кода проекта */
        Library project = project;
        ClassType[] classes = project.classes.clone();
        ArrayType[] arrays = arrays.clone();
        int clength = classes.length;
        int alength = arrays.length;
        int maxThreads = maxThreads;
        boolean isLibrary = library;
        boolean isStaticFieldsOnly = staticFieldsOnly;
        for(int cindex = 0; cindex < clength; cindex++)
        {
            ClassType type = classes[cindex];
            ClassInit staticBlock = type.getStaticBlock();
            for(int tlength = type.length, int mindex = 0; mindex < tlength; mindex++)
            {
                Member member = type[mindex];
                if(member instanceof Field) parseStaticFieldValue((Field) member, staticBlock);
            }
            if(staticBlock != null && staticBlock.declarationPosition < 0 && staticBlock.code.root.isEmpty()) type.removeStaticBlock();
        }
        if(isStaticFieldsOnly)
        {
            return;
        }
        if(!isLibrary)
        {
            int tlength = 0;
            ClassType[] types = null;
            for(LibraryArray libraries = libraries, int llength = libraries.length, int lindex = 0; lindex < llength; lindex++)
            {
                Library library = libraries[lindex];
                if(project != library)
                {
                    ClassType[] content = library.classes.clone();
                    if(types == null)
                    {
                        tlength = content.length;
                        Array.copy(content, 0, types = new ClassType[getBestArrayCapacity(tlength)], 0, tlength);
                    } else
                    {
                        int dlength = content.length;
                        int nlength = tlength + dlength;
                        if(nlength > types.length)
                        {
                            Array.copy(types, 0, types = new ClassType[getBestArrayCapacity(nlength)], 0, tlength);
                        }
                        Array.copy(content, 0, types, tlength, dlength);
                        tlength = nlength;
                    }
                }
            }
            if(tlength != types.length)
            {
                Array.copy(types, 0, types = new ClassType[tlength], 0, tlength);
            }
            with(new CompilerParallelWorker(maxThreads))
            {
                targets = types;
                run(new ImmediateBuilderForBinarySources(this));
            }
        }
        for(int cindex = 0; cindex < clength; cindex++)
        {
            ClassType type = classes[cindex];
            for(int tlength = type.length, int mindex = 0; mindex < tlength; mindex++)
            {
                Member member = type[mindex];
                if(!member.isAbstract() && member instanceof Property) parsePropertySpecifiers((Property) member);
            }
        }
        for(int aindex = 0; aindex < alength; aindex++)
        {
            ArrayType type = arrays[aindex];
            Type componentType = type.componentType;
            if(!(componentType instanceof PrimitiveType) && componentType != fldTypeObject)
            {
                alength = aindex;
                break;
            }
            for(int tlength = type.length, int tindex = 0; tindex < tlength; tindex++)
            {
                Member member = type[tindex];
                if(!member.isAbstract() && member instanceof Property) buildPropertySpecifiers((Property) member);
            }
        }
        {
            ClassType[] types = new ClassType[clength + alength];
            Array.copy(classes, 0, types, 0, clength);
            Array.copy(arrays, 0, types, clength, alength);
            with(fldThreadItemHolder = new CompilerParallelWorker(maxThreads)) try
            {
                targets = types;
                run(new ImmediateBuilderForTextSources(this));
            } finally
            {
                fldThreadItemHolder = null;
            }
        }
        /* 7. Стадия разметки данных */
        Type[] types = types.clone();
        int tlength = types.length;
        if(!isLibrary) for(int tindex = 0; tindex < tlength; tindex++)
        {
            Type type = types[tindex];
            if(type instanceof ClassType) ((ClassType) type).markupClass();
        }
        for(int tindex = 0; tindex < tlength; tindex++)
        {
            Type type = types[tindex];
            if(type instanceof ClassType) ((ClassType) type).markupStruct();
        }
    }

    public boolean library { read = fldLibrary }

    public boolean staticFieldsOnly { read = fldStaticFieldsOnly }

    final void readCallableBody(Callable callable) throws BinarySourceException, IOException {
        Code code = callable.code;
        ClassType enclosing = callable.parentType;
        BinarySource source = (BinarySource) callable.source;
        ConstantFactory factory = fldConstantFactory;
        Constant constFalse = fldFalse;
        Constant constTrue = fldTrue;
        Constant constNull = fldNull;
        Object[] constants = (Object[]) source[1];
        with(source.chunks[callable.declarationPosition + 1]) if(type == CHUNK_CODE && code != null)
        {
            /* чтение аргументов и локальных переменных */
            Hashtable primLocals = new Hashtable();
            Hashtable refsLocals = new Hashtable();
            ArgumentArray arguments = callable.arguments;
            Local thisArgument = arguments.thisArgument;
            if(thisArgument != null)
            {
                refsLocals[SPECNAME_THIS] = thisArgument;
            }
            for(int length = arguments.length, int index = 0; index < length; index++)
            {
                Local argument = arguments[index];
                (argument.type.isPrimitive() ? primLocals : refsLocals)[argument.specialSimpleName] = argument;
            }
            for(int length = readUnsignedShort(), int index = 0; index < length; index++)
            {
                int type = readInt();
                int name = readInt();
                String localName = (String) constants[name];
                Type localType = ((TypeElement) constants[type]).getItem();
                (localType.isPrimitive() ? primLocals : refsLocals)[localName] = code.createLocal(false, localType, localName, null, -1);
            }
            /* чтение перекомпилируемого кода */
            int dlength = 0x0f;
            int llength = 0x0f;
            int2[][] jmap = new int2[0x0f][];
            Node[] debugs = new Node[dlength];
            Node[] labels = new Node[llength];
            Type typeObject = fldTypeObject;
            Node root = code.root;
            for(int cindex = 0; available() > 0; cindex++)
            {
                if(cindex == jmap.length) Array.copy(jmap, 0, jmap = new int2[cindex << 1 | 1][], 0, cindex);
                int decoded;
                int lineIndex = -1;
                int labelIndex = -1;
                int debugIndex = -1;
                int encoded = readUnsignedShort();
                if(!isInstruction(encoded) && !decodeDeclareLabel(encoded))
                {
                    if(isLongNumber(encoded))
                    {
                        encoded = encoded << 0x10 | readUnsignedShort();
                    }
                    lineIndex = decodeDeclareNumber(encoded);
                    encoded = readUnsignedShort();
                }
                if(!isInstruction(encoded) && decodeDeclareLabel(encoded))
                {
                    if(isLongNumber(encoded))
                    {
                        encoded = encoded << 0x10 | readUnsignedShort();
                    }
                    if((decoded = decodeDeclareNumber(encoded)) >= 0)
                    {
                        labelIndex = decoded;
                    } else
                    {
                        debugIndex = ~decoded;
                        if(code.createDebugIndex(lineIndex) != debugIndex)
                        {
                            throw new BinarySourceException(package.getResourceString("binary.invalid-debug-label-index")) { source = source, offset = dataOffsetToSourceOffset(position) };
                        }
                    }
                    encoded = readUnsignedShort();
                }
                if(!isInstruction(encoded))
                {
                    throw new BinarySourceException(package.getResourceString("binary.expected.instruction-code")) { source = source, offset = dataOffsetToSourceOffset(position) };
                }
                boolean hasBooleanJump = false;
                Node node = null;
                switch(encoded >> 8)
                {
                case INST_METHOD_ENTER >> 8:
                    int operand1 = readIndex();
                    node = code.createAndAppendNode(root).setData(-1, METHOD_ENTER, new Int(operand1));
                    break;
                case INST_SWAP >> 8:
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, SWAP, operand1);
                    break;
                case INST_BOUND >> 8:
                    node = code.createAndAppendNode(root).setData(-1, BOUND);
                    break;
                case INST_THROW >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, THROW, operand1);
                    break;
                case INST_LOAD_STATIC >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int global = readIndex();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_STATIC, operand1);
                    break;
                case INST_LOAD_STATICW >> 8:
                    int global = readIndex();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_STATIC, operand1);
                    node.weak = true;
                    break;
                case INST_LOAD_LOCAL >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int local = readIndex();
                    Type operand2 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    Local operand1 = local <= 0 ? thisArgument : (Local) (decoded == REF ? refsLocals : primLocals).operator []((String) constants[local]);
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_LOCAL, operand1, operand2);
                    break;
                case INST_LOAD_LOCALW >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) refsLocals.operator []((String) constants[local]);
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_LOCAL, operand1, typeObject);
                    node.weak = true;
                    break;
                case INST_LOAD_CONST >> 8:
                case INST_LOAD_CONSTW >> 8:
                    int value = readIndex();
                    Object element = constants[value];
                    Constant operand1 = factory.createFrom(!(element instanceof RecompilableElement) ? element : ((RecompilableElement) element).getItem());
                    if(operand1.isClass()) ((Type) operand1.asObject()).makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_CONST, operand1);
                    if((encoded & FLAG_WEAK) != 0) node.weak = true;
                    break;
                case INST_READ_ELEMENT >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, READ_ELEMENT, operand1);
                    break;
                case INST_READ_ELEMENTI >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    Constant operand2 = factory.createInt(decodeVectorIndex(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, READ_ELEMENT, operand1, operand2);
                    break;
                case INST_READ_COMPONENT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, READ_COMPONENT, operand1, operand2);
                    break;
                case INST_READ_FIELD >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Field operand1 = ((FieldElement) constants[fieldoid]).getItem();
                    TableItem operand2 = getAdditionalOperand(operand, refsLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, READ_FIELD, operand1, operand2);
                    break;
                case INST_READ_SPECIAL >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Property operand1 = ((PropertyElement) constants[fieldoid]).getItem();
                    TableItem operand2 = getAdditionalOperand(operand, refsLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, READ_SPECIAL, operand1, operand2);
                    break;
                case INST_READ_PROPERTY >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Property operand1 = ((PropertyElement) constants[fieldoid]).getItem();
                    TableItem operand2 = getAdditionalOperand(operand, refsLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, READ_PROPERTY, operand1, operand2);
                    break;
                case INST_STORE_STATIC >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int global = readIndex();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_STATIC, operand1);
                    break;
                case INST_STORE_STATIC_NULL >> 8:
                    int global = readIndex();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_STATIC, operand1, constNull);
                    break;
                case INST_STORE_STATIC_SHORT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int global = readIndex();
                    int value = readShort();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    Constant operand2 = operand1.type.isBoolean() ? value != 0 ? constTrue : constFalse : factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_STATIC, operand1, operand2);
                    break;
                case INST_STORE_STATIC_INT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int global = readIndex();
                    int value = readInt();
                    Field operand1 = ((FieldElement) constants[global]).getItem();
                    Constant operand2 = operand1.type.isBoolean() ? value != 0 ? constTrue : constFalse : factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_STATIC, operand1, operand2);
                    break;
                case INST_STORE_LOCAL >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int store = decodeStore(encoded) - STORE_NORMAL;
                    int local = readIndex();
                    Type operand2 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    Local operand1 = local <= 0 ? thisArgument : (Local) (decoded == REF ? refsLocals : primLocals).operator []((String) constants[local]);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_LOCAL + store, operand1, operand2);
                    break;
                case INST_STORE_LOCAL_NULL >> 8:
                    int store = decodeStore(encoded) - STORE_NORMAL;
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) refsLocals.operator []((String) constants[local]);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_LOCAL + store, operand1, constNull);
                    break;
                case INST_STORE_LOCAL_SHORT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int store = decodeStore(encoded) - STORE_NORMAL;
                    int local = readIndex();
                    int value = readShort();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Constant operand2 = factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_LOCAL + store, operand1, operand2);
                    break;
                case INST_STORE_LOCAL_INT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int store = decodeStore(encoded) - STORE_NORMAL;
                    int local = readIndex();
                    int value = readInt();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Constant operand2 = factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, STORE_LOCAL + store, operand1, operand2);
                    break;
                case INST_INC_PRED_LOAD_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, INC_PRED_LOAD_LOCAL, operand1, operand2);
                    break;
                case INST_INC_POST_LOAD_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, INC_POST_LOAD_LOCAL, operand1, operand2);
                    break;
                case INST_DEC_PRED_LOAD_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, DEC_PRED_LOAD_LOCAL, operand1, operand2);
                    break;
                case INST_DEC_POST_LOAD_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, DEC_POST_LOAD_LOCAL, operand1, operand2);
                    break;
                case INST_WRITE_COMPONENT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, WRITE_COMPONENT, operand1);
                    break;
                case INST_WRITE_FIELD >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    Field operand1 = ((FieldElement) constants[fieldoid]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, WRITE_FIELD, operand1);
                    break;
                case INST_WRITE_SPECIAL >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    Property operand1 = ((PropertyElement) constants[fieldoid]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, WRITE_SPECIAL, operand1);
                    break;
                case INST_WRITE_PROPERTY >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int fieldoid = readIndex();
                    Property operand1 = ((PropertyElement) constants[fieldoid]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, WRITE_PROPERTY, operand1);
                    break;
                case INST_SWITCH_TABLE >> 8:
                    int jvalue = readInt();
                    int jlength = readIndex();
                    int2[] jumps = new int2[jlength + 1];
                    for(int jindex = 0; jindex < jlength; jvalue++, jindex++)
                    {
                        int jlabel = readLabel();
                        jumps[jindex] = new int2 { jlabel, jvalue };
                    }
                    {
                        int jlabel = readLabel();
                        jumps[jlength] = jlabel;
                    }
                    jmap[cindex] = jumps;
                    node = code.createAndAppendNode(root).setData(-1, BRANCH);
                    break;
                case INST_SWITCH_LOOKUP >> 8:
                    int jlength = readIndex();
                    int2[] jumps = new int2[jlength + 1];
                    for(int jindex = 0; jindex < jlength; jindex++)
                    {
                        int jvalue = readInt();
                        int jlabel = readLabel();
                        jumps[jindex] = new int2 { jlabel, jvalue };
                    }
                    {
                        int jlabel = readLabel();
                        jumps[jlength] = jlabel;
                    }
                    jmap[cindex] = jumps;
                    node = code.createAndAppendNode(root).setData(-1, BRANCH);
                    break;
                case INST_JUMP >> 8:
                    int jlabel = readLabel();
                    jmap[cindex] = new int2[] { jlabel };
                    node = code.createAndAppendNode(root).setData(-1, JUMP);
                    break;
                case INST_LOAD_INTERRUPT >> 8:
                    int method = readIndex();
                    Callable operand1 = ((CallableElement) constants[method]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_INTERRUPT, operand1);
                    break;
                case INST_LOAD_CONST_BYTE >> 8:
                    Constant operand1 = factory.createInt((byte) encoded);
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_CONST, operand1);
                    break;
                case INST_LOAD_CONST_NULL >> 8:
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_CONST, constNull);
                    break;
                case INST_LOAD_CONST_SHORT >> 8:
                    int value = readShort();
                    Constant operand1 = factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_CONST, operand1);
                    break;
                case INST_LOAD_CONST_INT >> 8:
                    int value = readInt();
                    Constant operand1 = factory.createInt(value);
                    node = code.createAndAppendNode(root).setData(-1, null, LOAD_CONST, operand1);
                    break;
                case INST_REF_EQ >> 8:
                case INST_REF_EQW >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    TableItem operand1 = getAdditionalOperand(operand, refsLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, REF_EQ, operand1);
                    if((encoded & FLAG_WEAK) != 0) node.weak = true;
                    break;
                case INST_REF_NE >> 8:
                case INST_REF_NEW >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    TableItem operand1 = getAdditionalOperand(operand, refsLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, REF_NE, operand1);
                    if((encoded & FLAG_WEAK) != 0) node.weak = true;
                    break;
                case INST_REF_IS_NULL >> 8:
                case INST_REF_IS_NULLW >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    node = code.createAndAppendNode(root).setData(-1, null, REF_IS_NULL);
                    if((encoded & FLAG_WEAK) != 0) node.weak = true;
                    break;
                case INST_REF_IS_OBJECT >> 8:
                case INST_REF_IS_OBJECTW >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    node = code.createAndAppendNode(root).setData(-1, null, REF_IS_OBJECT);
                    if((encoded & FLAG_WEAK) != 0) node.weak = true;
                    break;
                case INST_CLINIT_TRY_LOCK >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, CLINIT_TRY_LOCK, operand1);
                    break;
                case INST_CLINIT_UNLOCK >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, CLINIT_UNLOCK, operand1);
                    break;
                case INST_MONITOR_ENTER >> 8:
                    node = code.createAndAppendNode(root).setData(-1, MONITOR_ENTER);
                    break;
                case INST_MONITOR_LEAVE >> 8:
                    node = code.createAndAppendNode(root).setData(-1, MONITOR_LEAVE);
                    break;
                case INST_FINALLY_ENTER >> 8:
                    node = code.createAndAppendNode(root).setData(-1, FINALLY_ENTER);
                    break;
                case INST_FINALLY_LEAVE >> 8:
                    node = code.createAndAppendNode(root).setData(-1, FINALLY_LEAVE);
                    break;
                case INST_NEW_ARRAY >> 8:
                    int type = readIndex();
                    int length = readInt();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    Constant operand2 = factory.createInt(length);
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, NEW_ARRAY, operand1, operand2);
                    break;
                case INST_INVOKE_FINALLY >> 8:
                    int tlabel = readLabel();
                    jmap[cindex] = new int2[] { tlabel };
                    node = code.createAndAppendNode(root).setData(-1, INVOKE_FINALLY, null);
                    break;
                case INST_INVOKE_STATIC >> 8:
                case INST_INVOKE_STATICD >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int method = readIndex();
                    Callable operand1 = ((CallableElement) constants[method]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, INVOKE_STATIC, operand1);
                    if((encoded & FLAG_DISCARD) != 0) node.weak = true;
                    break;
                case INST_INVOKE_SPECIAL >> 8:
                case INST_INVOKE_SPECIALD >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int method = readIndex();
                    Callable operand1 = ((CallableElement) constants[method]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, INVOKE_SPECIAL, operand1);
                    if((encoded & FLAG_DISCARD) != 0) node.weak = true;
                    break;
                case INST_INVOKE_VIRTUAL >> 8:
                case INST_INVOKE_VIRTUALD >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int method = readIndex();
                    Callable operand1 = ((CallableElement) constants[method]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, INVOKE_VIRTUAL, operand1);
                    if((encoded & FLAG_DISCARD) != 0) node.weak = true;
                    break;
                case INST_INVOKE_SERVICE >> 8:
                case INST_INVOKE_SERVICED >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int method = readIndex();
                    Callable operand1 = ((CallableElement) constants[method]).getItem();
                    node = code.createAndAppendNode(root).setData(-1, null, INVOKE_SERVICE, operand1);
                    if((encoded & FLAG_DISCARD) != 0) node.weak = true;
                    break;
                case INST_VECT_DIV >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_DIV, operand1, operand2);
                    break;
                case INST_VECT_PCK >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_PCK, operand1);
                    break;
                case INST_VECT_LUP >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_LUP, operand1);
                    break;
                case INST_VECT_UUP >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_UUP, operand1);
                    break;
                case INST_VECT_MUL >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_MUL, operand1, operand2);
                    break;
                case INST_VECT_SHL >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SHL, operand1, operand2);
                    break;
                case INST_VECT_SHR >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SHR, operand1, operand2);
                    break;
                case INST_VECT_SHRU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SHRU, operand1, operand2);
                    break;
                case INST_VECT_ADD >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_ADD, operand1, operand2);
                    break;
                case INST_VECT_SUB >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SUB, operand1, operand2);
                    break;
                case INST_VECT_EQ >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_EQ, operand1, operand2);
                    break;
                case INST_VECT_NE >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_NE, operand1, operand2);
                    break;
                case INST_VECT_GT >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_GT, operand1, operand2);
                    break;
                case INST_VECT_GE >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_GE, operand1, operand2);
                    break;
                case INST_VECT_LT >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_LT, operand1, operand2);
                    break;
                case INST_VECT_LE >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_LE, operand1, operand2);
                    break;
                case INST_SCAL_DIV >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_DIV, operand1, operand2);
                    break;
                case INST_SCAL_DIVU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_DIVU, operand1, operand2);
                    break;
                case INST_SCAL_REM >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_REM, operand1, operand2);
                    break;
                case INST_SCAL_REMU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_REMU, operand1, operand2);
                    break;
                case INST_SCAL_MUL >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_MUL, operand1, operand2);
                    break;
                case INST_SCAL_SHL >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_SHL, operand1, operand2);
                    break;
                case INST_SCAL_SHR >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_SHR, operand1, operand2);
                    break;
                case INST_SCAL_SHRU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_SHRU, operand1, operand2);
                    break;
                case INST_SCAL_ADD >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_ADD, operand1, operand2);
                    break;
                case INST_SCAL_SUB >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_SUB, operand1, operand2);
                    break;
                case INST_SCAL_EQ >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_EQ, operand1, operand2);
                    break;
                case INST_SCAL_NE >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_NE, operand1, operand2);
                    break;
                case INST_SCAL_GT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_GT, operand1, operand2);
                    break;
                case INST_SCAL_GE >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_GE, operand1, operand2);
                    break;
                case INST_SCAL_LT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_LT, operand1, operand2);
                    break;
                case INST_SCAL_LE >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_LE, operand1, operand2);
                    break;
                case INST_VECT_NEG >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_NEG, operand1);
                    break;
                case INST_CAST_TO >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    Type operand2 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, CAST_TO, operand1, operand2);
                    break;
                case INST_INC_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, INC_LOCAL, operand1, operand2);
                    break;
                case INST_DEC_LOCAL >> 8:
                    int local = readIndex();
                    Local operand1 = local <= 0 ? thisArgument : (Local) primLocals.operator []((String) constants[local]);
                    Type operand2 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, DEC_LOCAL, operand1, operand2);
                    break;
                case INST_BIT_NOT >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_BIT_NOT, operand1);
                    break;
                case INST_BIT_AND >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_BIT_AND, operand1, operand2);
                    break;
                case INST_BIT_OR >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_BIT_OR, operand1, operand2);
                    break;
                case INST_BIT_XOR >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_BIT_XOR, operand1, operand2);
                    break;
                case INST_DUP1 >> 8:
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, DUP1, operand1);
                    break;
                case INST_DUP2 >> 8:
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, DUP2, operand1);
                    break;
                case INST_VECT_HMUL >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_HMUL, operand1, operand2);
                    break;
                case INST_VECT_HMULU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_HMULU, operand1, operand2);
                    break;
                case INST_VECT_SADD >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SADD, operand1, operand2);
                    break;
                case INST_VECT_SADDU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SADDU, operand1, operand2);
                    break;
                case INST_VECT_SSUB >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SSUB, operand1, operand2);
                    break;
                case INST_VECT_SSUBU >> 8:
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, O_VECT_SSUBU, operand1, operand2);
                    break;
                case INST_SCAL_NEG >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, O_SCAL_NEG, operand1);
                    break;
                case INST_INSTANCE_OF >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, INSTANCEOF, operand1);
                    break;
                case INST_TEST_EQZ >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, TEST_EQZ, operand1, operand2);
                    break;
                case INST_TEST_NEZ >> 8:
                    hasBooleanJump = (encoded & FLAG_BOOLEAN_JUMP) != 0;
                    int operand = decodeOperand(encoded);
                    int index = operand == OPERAND_NONE ? -1 : readIndex();
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    TableItem operand2 = getAdditionalOperand(operand, primLocals, constants, index);
                    node = code.createAndAppendNode(root).setData(-1, null, TEST_NEZ, operand1, operand2);
                    break;
                case INST_NEW_VECTOR >> 8:
                    Type operand1 = getPrimitiveType(decodeType(encoded));
                    node = code.createAndAppendNode(root).setData(-1, null, NEW_VECTOR, operand1);
                    break;
                case INST_NEW_INSTANCE >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, NEW_INSTANCE, operand1);
                    break;
                case INST_NEW_ARRAY_MONO >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, NEW_ARRAY_MONO, operand1);
                    break;
                case INST_NEW_ARRAY_MULTI >> 8:
                    int type = readIndex();
                    Type operand1 = ((TypeElement) constants[type]).getItem();
                    operand1.makeCompilable();
                    node = code.createAndAppendNode(root).setData(-1, null, NEW_ARRAY_MULTI, operand1);
                    break;
                case INST_DUP1X1 >> 8:
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, DUP1X1, operand1);
                    break;
                case INST_DUP1X2 >> 8:
                    Type operand1 = (decoded = decodeType(encoded)) == REF ? typeObject : getPrimitiveType(decoded);
                    node = code.createAndAppendNode(root).setData(-1, null, DUP1X2, operand1);
                    break;
                case INST_METHOD_LEAVE >> 8:
                    node = code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
                    break;
                case INST_EXCEPT_ENTER >> 8:
                    node = code.createAndAppendNode(root).setData(-1, EXCEPT_ENTER);
                    break;
                case INST_EXCEPT_TRY >> 8:
                    int blabel = readLabel();
                    int elabel = readLabel();
                    jmap[cindex] = new int2[] { blabel, elabel };
                    node = code.createAndAppendNode(root).setData(-1, EXCEPT_TRY, null, null);
                    break;
                case INST_EXCEPT_CATCH >> 8:
                    int blabel = readLabel();
                    int type = readIndex();
                    Type operand2 = ((TypeElement) constants[type]).getItem();
                    jmap[cindex] = new int2[] { blabel };
                    node = code.createAndAppendNode(root).setData(-1, EXCEPT_CATCH, null, operand2);
                    break;
                case INST_EXCEPT_FINALLY >> 8:
                    int blabel = readLabel();
                    jmap[cindex] = new int2[] { blabel };
                    node = code.createAndAppendNode(root).setData(-1, EXCEPT_FINALLY, null);
                    break;
                case INST_EXCEPT_LEAVE >> 8:
                    node = code.createAndAppendNode(root).setData(-1, EXCEPT_LEAVE);
                }
                if(hasBooleanJump)
                {
                    int tlabel = readLabel();
                    int flabel = readLabel();
                    jmap[cindex] = new int2[] { flabel, tlabel };
                }
                node.location = new int2 { lineIndex, -1 };
                if((node.debugIndex = debugIndex) >= 0)
                {
                    if(debugIndex >= dlength)
                    {
                        int capacity = getBestArrayCapacity(debugIndex + 1);
                        Array.copy(debugs, 0, debugs = new Node[capacity], 0, dlength);
                        dlength = capacity;
                    }
                    debugs[debugIndex] = node;
                }
                if((node.labelIndex = labelIndex) >= 0)
                {
                    if(labelIndex >= llength)
                    {
                        int capacity = getBestArrayCapacity(labelIndex + 1);
                        Array.copy(labels, 0, labels = new Node[capacity], 0, llength);
                        llength = capacity;
                    }
                    labels[labelIndex] = node;
                }
                code.assignOrder(node, cindex);
            }
            /* расстановка переходов */
            for(Node next = null, int cindex = root.length; cindex-- > 0; )
            {
                Node node = root[cindex];
                switch(node.instruction)
                {
                case BRANCH:
                    int2[] jumps = jmap[cindex];
                    int jlength = jumps.length - 1;
                    for(int jindex = 0; jindex < jlength; jindex++)
                    {
                        int2 jcase = jumps[jindex];
                        int jlabel = jcase[0];
                        node.setJumpCase(jcase[1], jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel]);
                    }
                    {
                        int2 jcase = jumps[jlength];
                        int jlabel = jcase[0];
                        node.jumpDefault = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    }
                    break;
                case JUMP:
                    int jlabel = jmap[cindex][0][0];
                    node.jumpDefault = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    break;
                case EXCEPT_CATCH:
                case EXCEPT_FINALLY:
                case INVOKE_FINALLY:
                    int jlabel = jmap[cindex][0][0];
                    node.reference1 = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    break;
                case EXCEPT_TRY:
                    int2[] jumps = jmap[cindex];
                    {
                        int jlabel = jumps[0][0];
                        node.reference1 = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    }
                    {
                        int jlabel = jumps[1][0];
                        node.reference2 = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    }
                    break;
                default:
                    int2[] jumps = jmap[cindex];
                    if(jumps == null)
                    {
                        break;
                    }
                    {
                        int jlabel = jumps[0][0];
                        node.jumpIsFalse = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    }
                    {
                        int jlabel = jumps[1][0];
                        node.jumpIsTrue = jlabel == NEXT ? next : jlabel < 0 ? debugs[~jlabel] : labels[jlabel];
                    }
                }
                next = node;
            }
        }
    }

    final void parseCallableBody(Callable callable) throws TextSourceException {
        Code code = callable.code;
        ClassType enclosing = callable.parentType;
        TextSource source = (TextSource) callable.source;
        if(source != null && callable.specialSimpleName.indexOf('.') < 0)
        {
            int position = callable.implementationPosition;
            label0:
            {
                label1:
                {
                    if(callable instanceof InstInit)
                    {
                        /* --- конструктор (метод инициализации объекта), добавленный компилятором --- */
                        if(position < 0)
                        {
                            position = enclosing.declarationPosition;
                            ClassType superclass = enclosing.getSuperclassType();
                            if(superclass == null)
                            {
                                /* вставка пустого тела */
                                Node root = code.root.setData(-1, METHOD_ENTER, null);
                                code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
                                break label0;
                            }
                            /* вставка инструкции вызова конструктора из суперкласса */
                            InstInit superconstructor = (InstInit) superclass.getChildCallable(SPECNAME_INST_INIT, (Type[]) null);
                            if(superconstructor == null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("required-explicit-constructor.no-default-constructor"), new Object[] { superclass.specialCanonicalName + ArgumentArray.toString(null) }
                                )) { source = source, position = position };
                            }
                            if(!superconstructor.isVisibleFrom(enclosing, enclosing))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("required-explicit-constructor.invisible-default-constructor"), new Object[] { superconstructor, enclosing.specialSimpleName }
                                )) { source = source, position = position };
                            }
                            ClassType type = getUnhandledException(superconstructor, null, callable);
                            if(type != null)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("required-explicit-constructor.unhandled-exception"), new Object[] { superconstructor, type }
                                )) { source = source, position = position };
                            }
                            Node root = code.root.setData(-1, METHOD_ENTER, null);
                            Node constructor = code.createAndPrependNode(root).setData(-1, null, INVOKE_SPECIAL, superconstructor);
                            code.createAndPrependNode(constructor).setData(-1, superclass, LOAD_LOCAL, callable.arguments.thisArgument);
                            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
                            break label0;
                        }
                        /* --- конструктор (метод инициализации объекта), написанный в исходном коде --- */
                        if(source.getLexemeKind(position) != COLON)
                        {
                            ClassType superclass = enclosing.getSuperclassType();
                            if(superclass != null)
                            {
                                /* вставка инструкции вызова конструктора из суперкласса */
                                InstInit superconstructor = (InstInit) superclass.getChildCallable(SPECNAME_INST_INIT, (Type[]) null);
                                if(superconstructor == null)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("required-explicit-constructor.no-default-constructor"),
                                        new Object[] { superclass.specialCanonicalName + ArgumentArray.toString(null) }
                                    )) { source = source, position = position };
                                }
                                if(!superconstructor.isVisibleFrom(enclosing, enclosing))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("required-explicit-constructor.invisible-default-constructor"), new Object[] { superconstructor, enclosing.specialSimpleName }
                                    )) { source = source, position = position };
                                }
                                ClassType type = getUnhandledException(superconstructor, null, callable);
                                if(type != null)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("required-explicit-constructor.unhandled-exception"), new Object[] { superconstructor, type }
                                    )) { source = source, position = position };
                                }
                                Node constructor = code.createAndPrependNode(null).setData(-1, null, INVOKE_SPECIAL, superconstructor);
                                code.createAndPrependNode(constructor).setData(-1, superclass, LOAD_LOCAL, callable.arguments.thisArgument);
                            }
                            break label1;
                        }
                        /* вставка вызова другого конструктора из этого класса или суперкласса */
                        ClassType place;
                        switch(source.getLexemeKind(++position))
                        {
                        case SUPER:
                            place = enclosing.getSuperclassType();
                            break;
                        case THIS:
                            place = enclosing;
                            break;
                        default:
                            throw new TextSourceException(package.getResourceString("expected.super-or-this")) { source = source, position = position };
                        }
                        if(place == null)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-use.super"), new Object[] { enclosing.specialSimpleName }
                            )) { source = source, position = position };
                        }
                        int before = position;
                        if(source.getLexemeKind(++position) != PARENTH_OPENED)
                        {
                            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
                        }
                        Node constructor = code.createAndPrependNode(null);
                        label2: if(source.getLexemeKind(++position) != PARENTH_CLOSED) do
                        {
                            position = parseExpression(constructor, source, position, true);
                            requiresValue(constructor[-1]);
                            switch(source.getLexemeKind(position))
                            {
                            default:
                                throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                            case PARENTH_CLOSED:
                                break label2;
                            case COMMA:
                                position++;
                            }
                        } while(true);
                        position++;
                        int length = constructor.length;
                        Type[] arguments = new Type[length];
                        for(int index = 0; index < length; index++) arguments[index] = constructor[index].type;
                        InstInit[] foundConstructors = place.findConstructors(arguments, enclosing);
                        int foundLength = foundConstructors == null ? 0 : foundConstructors.length;
                        if(foundLength < 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-found.constructor"),
                                new Object[] { place == enclosing ? place.specialSimpleName : place.specialCanonicalName, ArgumentArray.toString(arguments) }
                            )) { source = source, position = before };
                        }
                        InstInit foundConstructor = foundConstructors[0];
                        if(!foundConstructor.isConvertableArguments(arguments))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-applicable.constructor"), new Object[] { foundConstructor, ArgumentArray.toString(arguments) }
                            )) { source = source, position = before };
                        }
                        if(!foundConstructor.isVisibleFrom(enclosing, enclosing))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.constructor"), new Object[] { enclosing.specialSimpleName, foundConstructor }
                            )) { source = source, position = before };
                        }
                        if(foundLength > 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("ambiguous.constructor"),
                                new Object[] { (place == enclosing ? place.specialSimpleName : place.specialCanonicalName) + foundConstructor.arguments.toString() }
                            )) { source = source, position = before };
                        }
                        for(ArgumentArray foundArguments = foundConstructor.arguments, int index = 0; index < length; index++) cast(constructor[index], foundArguments[index].type);
                        code.createAndPrependNode(constructor).setData(before, place, LOAD_LOCAL, callable.arguments.thisArgument);
                        constructor.setData(before, null, INVOKE_SPECIAL, foundConstructor);
                        break label1;
                    }
                    if(callable instanceof ClassInit)
                    {
                        /* --- статичный блок (метод инициализации типа), добавленный компилятором --- */
                        if(position < 0)
                        {
                            position = enclosing.declarationPosition;
                            Node root = code.root.setData(-1, METHOD_ENTER, null);
                            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
                            break label0;
                        }
                        /* --- статичный блок (метод инициализации типа), написанный в исходном коде --- */
                        break label1;
                    }
                    if(code == null)
                    {
                        /* --- абстрактный или родной метод --- */
                        if(source.getLexemeKind(position) != SEMICOLON)
                        {
                            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
                        }
                        return;
                    }
                }
                /* чтение тела метода */
                if(source.getLexemeKind(position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                Node root = code.root.setData(position, METHOD_ENTER, null);
                label1: if(source.getLexemeKind(++position) != CURLY_CLOSED) do
                {
                    switch(source.getLexemeKind(position = parseControl(root, source, position)))
                    {
                    case L_END:
                        throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
                    case CURLY_CLOSED:
                        break label1;
                    }
                } while(true);
                code.createAndAppendNode(root).setData(position, METHOD_LEAVE);
            }
            /* проверка обязательной обработки исключений */
            label0: for(Node node = code.root, Node parent = null, int index = -1; ; )
            {
                label1: switch(node.instruction)
                {
                case INVOKE_STATIC:
                case INVOKE_SPECIAL:
                case INVOKE_VIRTUAL:
                case INVOKE_SERVICE:
                    ClassType type = null;
                    TableItem item = node.operand1;
                    if(item instanceof Method && (type = getUnhandledException((Method) item, parent, callable)) != null)
                    {
                        throw new TextSourceException(String.format(package.getResourceString("unhandled-exception"), new Object[] { type })) { source = source, position = node.position };
                    }
                    break;
                case THROW:
                    ClassType type = (ClassType) node.reference1;
                    if(!type.isFreeThrowableType() && !isHandledException(type, parent, callable))
                    {
                        throw new TextSourceException(String.format(package.getResourceString("unhandled-exception"), new Object[] { type })) { source = source, position = node.position };
                    }
                }
                if(node.length > 0)
                {
                    node = (parent = node)[index = 0];
                    continue;
                }
                if(parent == null)
                {
                    break;
                }
                if(++index < parent.length)
                {
                    node = parent[index];
                    continue;
                }
                do
                {
                    index = parent.index + 1;
                    if((parent = parent.parentNode) == null)
                    {
                        break label0;
                    }
                    if(index < parent.length)
                    {
                        node = parent[index];
                        break;
                    }
                } while(true);
            }
        }
        /* подготовка к дальнейшей работе с кодом */
        if(code == null) return;
        Node root = code.root;
        Node exit = root[-1];
        Constant constTrue = fldTrue;
        Constant constFalse = fldFalse;
        ClassType typeObject = fldTypeObject;
        PrimitiveType typeBoolean = fldTypeBoolean;
        /* обёртывание тела статичного блока специальными инструкциями */
        if(callable instanceof ClassInit)
        {
            enclosing.makeCompilable();
            Node control = code.createAndPrependNode(root).setData(-1, IF);
            code.createAndAppendNode(control).setData(-1, typeBoolean, CLINIT_TRY_LOCK, enclosing);
            Node blockTry = code.createAndAppendNode(control).setData(-1, TRY);
            Node cover = code.createAndAppendNode(blockTry).setData(-1, BEGIN);
            Node blockFinally = code.createAndAppendNode(blockTry).setData(-1, FINALLY_ENTER);
            code.createAndAppendNode(blockFinally).setData(-1, null, CLINIT_UNLOCK, enclosing);
            code.createAndAppendNode(blockFinally).setData(-1, FINALLY_LEAVE).special = true;
            blockTry = code.createAndAppendNode(cover).setData(-1, END);
            code.createAndAppendNode(blockTry).setData(-1, INVOKE_FINALLY, blockFinally).special = true;
            code.createAndAppendNode(blockTry).setData(-1, JUMP).special = true;
            for(int index = root.length - 1; index-- > 1; ) code.moveNode(root[index], cover, 0);
        }
        /* обёртывание синхронизированного метода специальными инструкциями */
        if(callable.isSynchronized())
        {
            Local monitor = code.createMonitorLocal(typeObject, !callable.isStatic() ? null : fldConstantFactory.createClass(enclosing));
            Node control = code.createAndPrependNode(root).setData(-1, BLOCK);
            Node declare = code.createAndAppendNode(control).setData(-1, null, DECLARE_LOCAL, monitor);
            Constant value = monitor.value;
            boolean isConstant = monitor.isConstant();
            if(!isConstant)
            {
                code.createAndAppendNode(declare).setData(-1, typeObject, LOAD_LOCAL, callable.arguments.thisArgument);
            }
            Node enter = code.createAndAppendNode(control).setData(-1, MONITOR_ENTER);
            if(isConstant)
            {
                code.createAndAppendNode(enter).setData(-1, typeObject, LOAD_CONST, value);
            } else
            {
                code.createAndAppendNode(enter).setData(-1, typeObject, LOAD_LOCAL, monitor);
            }
            Node blockTry = code.createAndAppendNode(control).setData(-1, TRY);
            Node cover = code.createAndAppendNode(blockTry).setData(-1, BEGIN);
            Node blockFinally = code.createAndAppendNode(blockTry).setData(-1, FINALLY_ENTER);
            Node leave = code.createAndAppendNode(blockFinally).setData(-1, MONITOR_LEAVE);
            if(isConstant)
            {
                code.createAndAppendNode(leave).setData(-1, typeObject, LOAD_CONST, value);
            } else
            {
                code.createAndAppendNode(leave).setData(-1, typeObject, LOAD_LOCAL, monitor);
            }
            code.createAndAppendNode(blockFinally).setData(-1, FINALLY_LEAVE).special = true;
            blockTry = code.createAndAppendNode(cover).setData(-1, END);
            code.createAndAppendNode(blockTry).setData(-1, INVOKE_FINALLY, blockFinally).special = true;
            code.createAndAppendNode(blockTry).setData(-1, JUMP).special = true;
            for(int index = root.length - 1; index-- > 1; ) code.moveNode(root[index], cover, 0);
        }
        /* вставка инструкций обработки исключений, дополнительных узлов, а также оптимизация кода */
        label0: for(code.createAndPrependNode(exit).setData(-1, EXCEPT_LEAVE), boolean isNeedExceptEnter = false, Node node = root, Node parent = null, int pindex = -1; ; )
        {
            if(node == exit)
            {
                if(isNeedExceptEnter) code.createAndPrependNode(exit).setData(-1, EXCEPT_ENTER);
                break;
            }
            label1:
            {
                int instruction = node.instruction;
                label2: switch(instruction)
                {
                case METHOD_ENTER:
                    if(callable.visibility > PRIVATE && (callable.isStatic() || callable instanceof InstInit))
                    {
                        ClassInit block = enclosing.getStaticBlock();
                        if(block != null && block != callable) code.createAndPrependNode(node).setData(node.position, null, INVOKE_STATIC, block);
                    }
                    break;
                case TRY:
                    for(isNeedExceptEnter = true, int nindex = node.length; nindex-- > 0; )
                    {
                        Node subblock = node[nindex];
                        switch(subblock.instruction)
                        {
                        case FINALLY_ENTER:
                            subblock.persistent = true;
                            code.createAndPrependNode(exit).setData(-1, EXCEPT_FINALLY, subblock);
                            break;
                        case CATCH:
                            Node markable = subblock[0];
                            markable.persistent = true;
                            code.createAndPrependNode(exit).setData(-1, EXCEPT_CATCH, markable, subblock.reference1);
                            break;
                        case BEGIN:
                            Node markable = subblock[-1];
                            subblock.persistent = true;
                            markable.persistent = true;
                            code.createAndPrependNode(exit).setData(-1, EXCEPT_TRY, subblock, markable);
                        }
                    }
                    break;
                case BREAK:
                case RETURN:
                case CONTINUE:
                    int position = node.position;
                    for(Object target = node.reference1, Node control = parent; control != null && control != target; control = control.parentNode)
                    {
                        Node block = control[-1];
                        if(control.instruction == TRY && block.instruction == FINALLY_ENTER) code.createAndAppendNode(node).setData(position, INVOKE_FINALLY, block);
                    }
                    if(instruction != RETURN)
                    {
                        code.createAndAppendNode(node).setData(position, JUMP);
                    }
                    break;
                case BOOL_COND:
                    if(!node.type.isBoolean())
                    {
                        code.createAndInsertNode(node, 2).setData(-1, JUMP);
                        break;
                    }
                    /* падение через */
                case BOOL_OR:
                case BOOL_AND:
                case BOOL_NOT:
                    switch(parent.instruction)
                    {
                    case IF:
                        if(pindex != 0) break;
                        break label2;
                    case DO:
                    case FOR:
                    case WHILE:
                        if(pindex != parent.length - 1) break;
                        break label2;
                    case BOOL_OR:
                    case BOOL_AND:
                    case BOOL_NOT:
                    case BOOL_COND:
                        break label2;
                    }
                    if(instruction == BOOL_COND && !isLogicalConditionNode(node))
                    {
                        code.createAndInsertNode(node, 2).setData(-1, JUMP);
                        break;
                    }
                    Node cover = code.createAndInsertNode(parent, pindex).setData(-1, typeBoolean, BOOL_COND);
                    code.moveNode(node, node = cover, 0);
                    code.createAndAppendNode(cover).setData(-1, typeBoolean, LOAD_CONST, constTrue);
                    code.createAndAppendNode(cover).setData(-1, JUMP);
                    code.createAndAppendNode(cover).setData(-1, typeBoolean, LOAD_CONST, constFalse);
                    break;
                case REF_EQ:
                case REF_NE:
                    Node child;
                    Node relation1 = node[0];
                    Node relation2 = node[1];
                    label3:
                    {
                        if(relation1.instruction == LOAD_CONST && ((Constant) relation1.operand1).isNull())
                        {
                            node.instruction = instruction + (REF_IS_NULL - REF_EQ);
                            code.removeNode(relation1);
                            child = relation2;
                            break label3;
                        }
                        if(relation2.instruction == LOAD_CONST && ((Constant) relation2.operand1).isNull())
                        {
                            node.instruction = instruction + (REF_IS_NULL - REF_EQ);
                            code.removeNode(relation2);
                            child = relation1;
                            break label3;
                        }
                        break;
                    }
                    if((instruction = child.instruction) == LOAD_STATIC || instruction == LOAD_LOCAL || instruction == LOAD_CONST && !((Constant) child.operand1).isString())
                    {
                        node.weak = child.weak = true;
                    }
                    break;
                case O_SCAL_EQ:
                case O_SCAL_NE:
                    if(((Type) node.operand1).isLong())
                    {
                        Node relation1 = node[0];
                        Node relation2 = node[1];
                        if(relation1.instruction == O_BIT_AND && relation2.instruction == LOAD_CONST && ((Constant) relation2.operand1).isDefaultValue())
                        {
                            node.instruction = instruction + (TEST_EQZ - O_SCAL_EQ);
                            code.moveNode(relation1[0], node, 0);
                            code.moveNode(relation1[0], node, 1);
                            code.removeNode(relation1);
                            code.removeNode(relation2);
                            break;
                        }
                        if(relation2.instruction == O_BIT_AND && relation1.instruction == LOAD_CONST && ((Constant) relation1.operand1).isDefaultValue())
                        {
                            node.instruction = instruction + (TEST_EQZ - O_SCAL_EQ);
                            code.moveNode(relation2[0], node, 0);
                            code.moveNode(relation2[0], node, 1);
                            code.removeNode(relation1);
                            code.removeNode(relation2);
                        }
                    }
                    break;
                case LOAD_STATIC:
                    ClassType type = ((Member) node.operand1).parentType;
                    if(enclosing != type)
                    {
                        ClassInit block = type.getStaticBlock();
                        if(block != null)
                        {
                            code.createAndPrependNode(node).setData(node.position, null, INVOKE_STATIC, block);
                            break;
                        }
                    }
                    /* падение через */
                case LOAD_LOCAL:
                case LOAD_CONST:
                    if(pindex == parent.length - 1)
                    {
                        switch(parent.instruction)
                        {
                        default:
                            break label2;
                        case STORE_LOCAL:
                        case STORE_STATIC:
                        case DECLARE_WITH:
                        case DECLARE_LOCAL:
                            if(pindex == 0 && instruction == LOAD_CONST)
                            {
                                Constant value = (Constant) node.operand1;
                                Type type = value.type;
                                if(type.isInt() || type.isBoolean() || value.isNull())
                                {
                                    parent.operand2 = value;
                                    break;
                                }
                            }
                            break label2;
                        case REF_EQ:
                        case REF_NE:
                            if(instruction == LOAD_CONST && ((Constant) node.operand1).isString()) break label2;
                            Node child = parent[0];
                            if((instruction = child.instruction) == LOAD_STATIC || instruction == LOAD_LOCAL || instruction == LOAD_CONST && !((Constant) child.operand1).isString())
                            {
                                parent.weak = child.weak = true;
                            }
                            parent.operand1 = node.operand1;
                            break;
                        case READ_ELEMENT:
                            if(instruction != LOAD_CONST) break label2;
                            parent.operand2 = node.operand1;
                            break;
                        case READ_FIELD:
                        case READ_SPECIAL:
                        case READ_PROPERTY:
                            if(instruction == LOAD_CONST && ((Constant) node.operand1).isString()) break label2;
                            /* падение через */
                        case READ_COMPONENT:
                        case TEST_EQZ:
                        case TEST_NEZ:
                        case O_BIT_AND:
                        case O_BIT_OR:
                        case O_BIT_XOR:
                        case O_SCAL_MUL:
                        case O_SCAL_DIV:
                        case O_SCAL_DIVU:
                        case O_SCAL_REM:
                        case O_SCAL_REMU:
                        case O_SCAL_ADD:
                        case O_SCAL_SUB:
                        case O_SCAL_SHR:
                        case O_SCAL_SHRU:
                        case O_SCAL_SHL:
                        case O_SCAL_GT:
                        case O_SCAL_GE:
                        case O_SCAL_LT:
                        case O_SCAL_LE:
                        case O_SCAL_EQ:
                        case O_SCAL_NE:
                        case O_VECT_MUL:
                        case O_VECT_DIV:
                        case O_VECT_ADD:
                        case O_VECT_SUB:
                        case O_VECT_SHR:
                        case O_VECT_SHRU:
                        case O_VECT_SHL:
                        case O_VECT_GT:
                        case O_VECT_GE:
                        case O_VECT_LT:
                        case O_VECT_LE:
                        case O_VECT_EQ:
                        case O_VECT_NE:
                        case O_VECT_HMUL:
                        case O_VECT_HMULU:
                        case O_VECT_SADD:
                        case O_VECT_SADDU:
                        case O_VECT_SSUB:
                        case O_VECT_SSUBU:
                            parent.operand2 = node.operand1;
                        }
                        code.removeNode(node);
                        pindex--;
                        break label1;
                    }
                }
                if(node.length > 0)
                {
                    node = (parent = node)[pindex = 0];
                    continue;
                }
                if(parent == null) break;
            }
            if(++pindex < parent.length)
            {
                node = parent[pindex];
                continue;
            }
            do
            {
                pindex = parent.index + 1;
                if((parent = parent.parentNode) == null)
                {
                    break label0;
                }
                if(pindex < parent.length)
                {
                    node = parent[pindex];
                    break;
                }
            } while(true);
        }
        /* нумерация узлов */
        label0: for(code.assignOrder(root, 0), Node node = root, Node parent = null, int pindex = -1; ; )
        {
            int order = node.order;
            switch(node.instruction)
            {
            case NOP:
            case IF:
            case SWITCH:
            case CASE:
            case DEFAULT:
            case LABEL:
            case DO:
            case FOR:
            case WHILE:
            case BLOCK:
            case BREAK:
            case CONTINUE:
            case TRY:
            case CATCH:
            case BOOL_OR:
            case BOOL_AND:
            case BOOL_NOT:
            case BOOL_COND:
                /* нумеруются только дочерние узлы, этот узел не нумеруется */
                for(code.clearOrder(node), int nlength = node.length, int nindex = 0; nindex < nlength; nindex++)
                {
                    code.assignOrder(node[nindex], order++);
                }
                break;
            case BEGIN:
            case FINALLY_ENTER:
            case METHOD_ENTER:
            case METHOD_LEAVE:
            case NEW_ARRAY:
            case NEW_INSTANCE:
                /* сперва нумеруется этот узел, а затем — дочерние узлы */
                for(int nlength = node.length, int nindex = 0; nindex < nlength; nindex++)
                {
                    code.assignOrder(node[nindex], ++order);
                }
                break;
            case DECLARE_WITH:
            case DECLARE_LOCAL:
                /* не нумеруется узел с объявлением локальной константы */
                if(node.isEmpty() && ((Local) node.operand1).isConstant())
                {
                    code.clearOrder(node);
                }
                /* падение через */
            default:
                /* сперва нумеруются дочерние узлы, а затем — этот узел */
                for(int nlength = node.length, int nindex = 0; nindex < nlength; nindex++)
                {
                    code.assignOrder(node[nindex], order++);
                }
            }
            if(node.length > 0)
            {
                node = (parent = node)[pindex = 0];
                continue;
            }
            if(parent == null)
            {
                break;
            }
            if(++pindex < parent.length)
            {
                node = parent[pindex];
                continue;
            }
            do
            {
                pindex = parent.index + 1;
                if((parent = parent.parentNode) == null)
                {
                    break label0;
                }
                if(pindex < parent.length)
                {
                    node = parent[pindex];
                    break;
                }
            } while(true);
        }
        /* расстановка переходов и замена условных переходов по константам типа boolean на безусловные переходы */
        label0: for(Node node = root, Node parent = null, int pindex = -1; ; )
        {
            switch(node.instruction)
            {
            case IF:
                boolean hasElse = node.length > 3;
                int after = node.maxOrder() + 1;
                int isTrue = node[1].minOrder();
                int isFalse = !hasElse ? after : node[3].minOrder();
                if(isTrue < 0) isTrue = after;
                if(isFalse < 0) isFalse = after;
                with(node[0])
                {
                    jumpIsTrue = code[isTrue];
                    jumpIsFalse = code[isFalse];
                }
                if(hasElse)
                {
                    node[2].jumpDefault = code[after];
                }
                break;
            case SWITCH:
                int after = node.maxOrder() + 1;
                with(node[0]) for(int nindex = node.length; nindex-- > 1; )
                {
                    Node subnode = node[nindex];
                    int isCase = subnode.minOrder();
                    if(isCase < 0)
                    {
                        isCase = after;
                    } else
                    {
                        after = isCase;
                    }
                    if(subnode.instruction == CASE)
                    {
                        setJumpCase(((Int) subnode.reference1).intValue, code[isCase]);
                        continue;
                    }
                    jumpDefault = code[isCase];
                }
                break;
            case DO:
                int after = node.maxOrder() + 1;
                int isTrue = node[-2].minOrder();
                with(node[-1])
                {
                    if(isTrue < 0) isTrue = minOrder();
                    jumpIsTrue = code[isTrue];
                    jumpIsFalse = code[after];
                }
                break;
            case FOR:
                int after = node.maxOrder() + 1;
                int isTrue = node[-3].minOrder();
                with(node[-1])
                {
                    int condition = minOrder();
                    if(isTrue < 0 && (isTrue = node[-2].minOrder()) < 0) isTrue = condition;
                    node[-4].jumpDefault = code[condition];
                    jumpIsTrue = code[isTrue];
                    jumpIsFalse = code[after];
                }
                break;
            case WHILE:
                int after = node.maxOrder() + 1;
                int isTrue = node[-2].minOrder();
                with(node[-1])
                {
                    int condition = minOrder();
                    if(isTrue < 0) isTrue = condition;
                    node[-3].jumpDefault = code[condition];
                    jumpIsTrue = code[isTrue];
                    jumpIsFalse = code[after];
                }
                break;
            case BREAK:
                node[-1].jumpDefault = code.operator [](((Node) node.reference1).maxOrder() + 1);
                break;
            case CONTINUE:
                int condition;
                Node target = (Node) node.reference1;
                if(target.instruction != FOR)
                {
                    condition = target[-1].minOrder();
                } else
                {
                    int step = target[-2].minOrder();
                    condition = step >= 0 ? step : target[-1].minOrder();
                }
                node[-1].jumpDefault = code[condition];
                break;
            case RETURN:
                node.jumpDefault = exit;
                break;
            case TRY:
                for(Node after = code.operator [](node.maxOrder() + 1), node[0][-1][-1].jumpDefault = after, int nindex = node.length - 1; nindex-- > 1; )
                {
                    node[nindex][-1].jumpDefault = after;
                }
                break;
            case BOOL_OR:
                Node isTrue = node.jumpIsTrue;
                Node isFalse = node.jumpIsFalse;
                Node subnode0 = node[0];
                Node subnode1 = node[1];
                subnode0.jumpIsTrue = isTrue;
                subnode0.jumpIsFalse = code.operator [](subnode1.minOrder());
                subnode1.jumpIsTrue = isTrue;
                subnode1.jumpIsFalse = isFalse;
                node.jumpIsTrue = null;
                node.jumpIsFalse = null;
                break;
            case BOOL_AND:
                Node isTrue = node.jumpIsTrue;
                Node isFalse = node.jumpIsFalse;
                Node subnode0 = node[0];
                Node subnode1 = node[1];
                subnode0.jumpIsTrue = code.operator [](subnode1.minOrder());
                subnode0.jumpIsFalse = isFalse;
                subnode1.jumpIsTrue = isTrue;
                subnode1.jumpIsFalse = isFalse;
                node.jumpIsTrue = null;
                node.jumpIsFalse = null;
                break;
            case BOOL_NOT:
                Node isTrue = node.jumpIsTrue;
                Node isFalse = node.jumpIsFalse;
                with(node[0])
                {
                    jumpIsTrue = isFalse;
                    jumpIsFalse = isTrue;
                }
                node.jumpIsTrue = null;
                node.jumpIsFalse = null;
                break;
            case BOOL_COND:
                Node isTrue = node.jumpIsTrue;
                Node isFalse = node.jumpIsFalse;
                Node branchTrue = node[1];
                Node branchFalse = node[-1];
                with(node[0])
                {
                    jumpIsTrue = code.operator [](branchTrue.minOrder());
                    jumpIsFalse = code.operator [](branchFalse.minOrder());
                }
                if(isTrue == null || isFalse == null)
                {
                    node[2].jumpDefault = code.operator [](node.maxOrder() + 1);
                } else
                {
                    branchTrue.jumpIsTrue = branchFalse.jumpIsTrue = isTrue;
                    branchTrue.jumpIsFalse = branchFalse.jumpIsFalse = isFalse;
                }
                node.jumpIsTrue = null;
                node.jumpIsFalse = null;
                break;
            case LOAD_CONST:
                Node isTrue = node.jumpIsTrue;
                Node isFalse = node.jumpIsFalse;
                Constant value = (Constant) node.operand1;
                if(value.isBoolean() && isTrue != null && isFalse != null)
                {
                    node.setData(node.position, JUMP);
                    node.clearJumpCases();
                    node.jumpDefault = value.asBoolean() ? isTrue : isFalse;
                }
                break;
            case METHOD_LEAVE:
                node.special = true;
                /* падение через */
            case THROW:
            case FINALLY_LEAVE:
                node.endPoint = true;
            }
            if(node.length > 0)
            {
                node = (parent = node)[pindex = 0];
                continue;
            }
            if(parent == null)
            {
                break;
            }
            if(++pindex < parent.length)
            {
                node = parent[pindex];
                continue;
            }
            do
            {
                pindex = parent.index + 1;
                if((parent = parent.parentNode) == null)
                {
                    break label0;
                }
                if(pindex < parent.length)
                {
                    node = parent[pindex];
                    break;
                }
            } while(true);
        }
        /* проверка и оптимизация связности кода */
        {
            int clength = code.length;
            byte[] attainability = new byte[clength];
            /* проверка наличия недостижимых узлов и отмена нумерации для специальных из них */
            {
                Node unattained = null;
                defineAttainability(attainability, code, clength);
                for(int cindex = clength - 1; cindex >= 0 && (cindex = Array.lastIndexOf(0, attainability, cindex, 0)) >= 0; )
                {
                    Node node = code[cindex--];
                    if(!node.special || node.instruction == BEGIN)
                    {
                        unattained = node;
                        continue;
                    }
                    if(!node.persistent)
                    {
                        clength--;
                        code.clearOrder(node);
                    }
                }
                if(unattained != null) do
                {
                    int position = unattained.position;
                    if(position >= 0)
                    {
                        throw new TextSourceException(package.getResourceString("detected.unreachable-code")) { source = source, position = position };
                    }
                    if(unattained.instruction == JUMP)
                    {
                        unattained = unattained.jumpDefault;
                        continue;
                    }
                    unattained = code[unattained.order + 1];
                } while(true);
            }
            /* проверка обязательного возвращения значения */
            if(!callable.type.isVoid()) for(int cindex = clength; cindex-- > 0; )
            {
                Node node = code[cindex];
                if(node.instruction != RETURN && node.hasJumpsTo(exit))
                {
                    throw new TextSourceException(package.getResourceString("required.return")) { source = source, position = exit.position };
                }
            }
            /* оптимизация переходов, отмена нумерации для узлов — переходов на следующий по номеру узел */
            for(Node[] jumps = new Node[0x0f], int jlength = 0, int cindex = clength; cindex-- > 0; )
            {
                Node node = code[cindex];
                int instruction = node.instruction;
                int jindex = node.getJumpCasesLength();
                if(instruction != JUMP && instruction != RETURN)
                {
                    if(instruction == BEGIN) node.position = -1;
                    if(jindex <= 0) continue;
                    jlength = 0;
                } else
                {
                    Node target = node.jumpDefault;
                    if(target.order == node.order + 1)
                    {
                        clength--;
                        code.clearOrder(node);
                        code.replaceJumpNode(node, target);
                        continue;
                    }
                    jlength = 1;
                    jumps[0] = node;
                }
                while(jindex-- > -1)
                {
                    Node target = jindex < 0 ? node.jumpDefault : node.getJumpCaseNodeAt(jindex);
                    if(target != null)
                    {
                        while(((instruction = target.instruction) == RETURN || instruction == JUMP) && (jlength <= 0 || Array.indexOf(target, jumps, 0, jlength) < 0))
                        {
                            if(jlength == jumps.length) Array.copy(jumps, 0, jumps = new Node[jlength << 1 | 1], 0, jlength);
                            jumps[jlength++] = target;
                            target = target.jumpDefault;
                        }
                        if(jindex < 0)
                        {
                            node.jumpDefault = target;
                            continue;
                        }
                        node.setJumpCase(node.getJumpCaseValueAt(jindex), target);
                    }
                }
            }
            /* отмена нумерации для недостижимых узлов, возможно образовавшихся в результате оптимизации переходов */
            {
                Array.fill(attainability, 0, clength, 0);
                defineAttainability(attainability, code, clength);
                for(int cindex = clength - 1; cindex >= 0 && (cindex = Array.lastIndexOf(0, attainability, cindex, 0)) >= 0; )
                {
                    Node node = code[cindex--];
                    if(!node.persistent) code.clearOrder(node);
                }
            }
        }
        /* массив инструкций */
        Node[] list = code.clone();
        int clength = list.length;
        /* расстановка меток */
        {
            for(Node next = null, int cindex = clength; cindex-- > 0; )
            {
                Node node = list[cindex];
                if(node.persistent)
                {
                    node.labelIndex = 0;
                }
                for(int jindex = node.getJumpCasesLength(); jindex-- > -1; )
                {
                    Node target = jindex < 0 ? node.jumpDefault : node.getJumpCaseNodeAt(jindex);
                    if(target != null && target != next) target.labelIndex = 0;
                }
                next = node;
            }
            for(int labelIndex = 0, int lastIndex = -1, int cindex = 0; cindex < clength; cindex++)
            {
                Node node = list[cindex];
                int lineIndex = (int) node.location;
                if(lineIndex >= 0 && lastIndex != lineIndex)
                {
                    node.labelIndex = -1;
                    node.debugIndex = code.createDebugIndex(lineIndex);
                    lastIndex = lineIndex;
                    continue;
                }
                if(node.labelIndex == 0) node.labelIndex = labelIndex++;
            }
        }
        /* определение максимального количества занимаемых элементов стака */
        {
            ElementStack stack = new ElementStack();
            for(int cindex = 1; cindex < clength; cindex++)
            {
                Node node = list[cindex];
                int stackElements = node.stackElements;
                if(stackElements >= 0)
                {
                    stack.stackElements = stackElements;
                }
                switch(node.instruction)
                {
                default:
                    continue;
                case INSTANCEOF:
                case REF_IS_NULL:
                case REF_IS_OBJECT:
                    break;
                case RETURN:
                case METHOD_LEAVE:
                    stack.reset();
                    continue;
                case THROW:
                case BRANCH:
                case FINALLY_LEAVE:
                case MONITOR_ENTER:
                case MONITOR_LEAVE:
                    stack.change(-1);
                    continue;
                case CLINIT_TRY_LOCK:
                    stack.change(+1);
                    break;
                case NEW_ARRAY:
                case NEW_INSTANCE:
                case FINALLY_ENTER:
                case LOAD_INTERRUPT:
                    stack.change(+1);
                    continue;
                case LOAD_CONST:
                case LOAD_LOCAL:
                case LOAD_STATIC:
                    stack.change(((TypedItem) node.operand1).type.stackElements);
                    break;
                case INC_PRED_LOAD_LOCAL:
                case DEC_PRED_LOAD_LOCAL:
                case INC_POST_LOAD_LOCAL:
                case DEC_POST_LOAD_LOCAL:
                    stack.change(((TypedItem) node.operand1).type.stackElements);
                    continue;
                case READ_ELEMENT:
                    stack.change((node.operand2 == null ? +0 : +1) - ((Type) node.operand1).stackElements);
                    continue;
                case READ_COMPONENT:
                    stack.change((node.operand2 == null ? -2 : -1) + ((Type) node.operand1).stackElements);
                    break;
                case READ_FIELD:
                case READ_SPECIAL:
                case READ_PROPERTY:
                    stack.change((node.operand2 == null ? -1 : +0) + ((TypedItem) node.operand1).type.stackElements);
                    break;
                case DUP1:
                case DUP1X1:
                case DUP1X2:
                    stack.change(((Type) node.operand1).stackElements);
                    continue;
                case DUP2:
                    stack.change(((Type) node.operand1).stackElements + 1);
                    continue;
                case INVOKE_STATIC:
                case INVOKE_SPECIAL:
                case INVOKE_VIRTUAL:
                case INVOKE_SERVICE:
                    Callable method = (Callable) node.operand1;
                    stack.change((node.weak ? +0 : method.type.stackElements) - method.arguments.stackElements);
                    break;
                case NEW_VECTOR:
                    PrimitiveType type = (PrimitiveType) node.operand1;
                    stack.change(type.stackElements - type.vectorLength);
                    continue;
                case CAST_TO:
                    stack.change(((Type) node.operand1).stackElements - ((Type) node.operand2).stackElements);
                    continue;
                case REF_EQ:
                case REF_NE:
                    stack.change(node.operand1 != null ? +0 : -1);
                    break;
                case TEST_EQZ:
                case TEST_NEZ:
                    stack.change(node.operand2 != null ? +0 : -1);
                    break;
                case O_BIT_OR:
                case O_BIT_AND:
                case O_BIT_XOR:
                    stack.change(node.operand2 != null ? +0 : -((Type) node.operand1).stackElements);
                    break;
                case O_SCAL_MUL:
                case O_SCAL_DIV:
                case O_SCAL_DIVU:
                case O_SCAL_REM:
                case O_SCAL_REMU:
                case O_SCAL_ADD:
                case O_SCAL_SUB:
                case O_VECT_MUL:
                case O_VECT_DIV:
                case O_VECT_ADD:
                case O_VECT_SUB:
                case O_VECT_EQ:
                case O_VECT_NE:
                case O_VECT_GT:
                case O_VECT_GE:
                case O_VECT_LT:
                case O_VECT_LE:
                case O_VECT_HMUL:
                case O_VECT_HMULU:
                case O_VECT_SADD:
                case O_VECT_SADDU:
                case O_VECT_SSUB:
                case O_VECT_SSUBU:
                    stack.change(node.operand2 != null ? +0 : -((Type) node.operand1).stackElements);
                    continue;
                case O_SCAL_SHR:
                case O_SCAL_SHRU:
                case O_SCAL_SHL:
                case O_VECT_SHR:
                case O_VECT_SHRU:
                case O_VECT_SHL:
                    stack.change(node.operand2 != null ? +0 : -1);
                    continue;
                case O_SCAL_EQ:
                case O_SCAL_NE:
                case O_SCAL_GT:
                case O_SCAL_GE:
                case O_SCAL_LT:
                case O_SCAL_LE:
                    stack.change(1 - (((Type) node.operand1).stackElements << (node.operand2 == null ? 1 : 0)));
                    break;
                case O_VECT_LUP:
                case O_VECT_UUP:
                case O_VECT_PCK:
                    stack.change(node.type.stackElements - ((Type) node.operand1).stackElements);
                    continue;
                case STORE_LOCAL:
                case STORE_STATIC:
                case DECLARE_WITH:
                case DECLARE_LOCAL:
                    stack.change(node.operand2 != null ? +0 : -((TypedItem) node.operand1).type.stackElements);
                    break;
                case WRITE_COMPONENT:
                    stack.change(-(((Type) node.operand1).stackElements + 2));
                    break;
                case WRITE_FIELD:
                case WRITE_SPECIAL:
                case WRITE_PROPERTY:
                    stack.change(-(((TypedItem) node.operand1).type.stackElements + 1));
                }
                Node jumpIsTrue = node.jumpIsTrue;
                Node jumpIsFalse = node.jumpIsFalse;
                if(jumpIsTrue != null && jumpIsFalse != null)
                {
                    stack.change(-1);
                    if(jumpIsTrue.order > cindex && jumpIsFalse.order > cindex) jumpIsTrue.stackElements = jumpIsFalse.stackElements = stack.stackElements;
                }
            }
            root.setData(root.position, METHOD_ENTER, new Int(stack.maximumElements));
        }
    }

    private void buildPropertySpecifiers(Property property) {
        ClassType factEnclosing = property.parentType;
        ClassType realEnclosing = factEnclosing.getRealType();
        Method method = property.indexSynthetic;
        TypedMember indexMember = property.indexMember;
        Constant indexConstant = property.indexConstant;
        boolean hasIndex = indexConstant != null || indexMember != null;
        label0: if(method != null)
        {
            Type type = method.type;
            Code code = method.code;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(indexConstant != null)
            {
                code.createAndAppendNode(control).setData(-1, type, LOAD_CONST, indexConstant.castTo(type));
                break label0;
            }
            if(indexMember instanceof Field)
            {
                Node value = code.createAndAppendNode(control).setData(-1, indexMember.type, READ_FIELD, indexMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
                break label0;
            }
            if(indexMember instanceof Method)
            {
                Node value = code.createAndAppendNode(control).setData(-1, indexMember.type, invokeInstructionFor(indexMember, factEnclosing), indexMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
            }
        }
        label0: if((method = property.readSynthetic) != null)
        {
            Type type = method.type;
            Code code = method.code;
            TypedMember readMember = property.readMember;
            Constant readConstant = property.readConstant;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(readConstant != null)
            {
                code.createAndAppendNode(control).setData(-1, type, LOAD_CONST, readConstant.castTo(type));
                break label0;
            }
            if(readMember instanceof Field)
            {
                Node value = code.createAndAppendNode(control).setData(-1, readMember.type, READ_FIELD, readMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
                break label0;
            }
            if(readMember instanceof Method)
            {
                Node value = code.createAndAppendNode(control).setData(-1, readMember.type, invokeInstructionFor(readMember, factEnclosing), readMember);
                if(hasIndex) appendPropertyIndexCode(-1, value, indexConstant, indexMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
            }
        }
        label0: if((method = property.writeSynthetic) != null)
        {
            Code code = method.code;
            Local value = method.getArgument(SPECNAME_VALUE);
            TypedMember writeMember = property.writeMember;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(writeMember instanceof Field)
            {
                Node write = code.createAndPrependNode(root).setData(-1, null, WRITE_FIELD, writeMember);
                code.createAndAppendNode(write).setData(-1, value.type, LOAD_LOCAL, value);
                code.createAndPrependNode(write).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                break label0;
            }
            if(writeMember instanceof Method)
            {
                Node write = code.createAndPrependNode(root).setData(-1, null, invokeInstructionFor(writeMember, factEnclosing), writeMember);
                if(hasIndex) appendPropertyIndexCode(-1, write, indexConstant, indexMember);
                code.createAndAppendNode(write).setData(-1, value.type, LOAD_LOCAL, value);
                code.createAndPrependNode(write).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
            }
        }
        label0: if((method = property.storedSynthetic) != null)
        {
            Type type = method.type;
            Code code = method.code;
            TypedMember storedMember = property.storedMember;
            Constant storedConstant = property.storedConstant;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(storedConstant != null)
            {
                code.createAndAppendNode(control).setData(-1, type, LOAD_CONST, storedConstant.castTo(type));
                break label0;
            }
            if(storedMember instanceof Field)
            {
                Node value = code.createAndAppendNode(control).setData(-1, storedMember.type, READ_FIELD, storedMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
                break label0;
            }
            if(storedMember instanceof Method)
            {
                Node value = code.createAndAppendNode(control).setData(-1, storedMember.type, invokeInstructionFor(storedMember, factEnclosing), storedMember);
                if(hasIndex) appendPropertyIndexCode(-1, value, indexConstant, indexMember);
                code.createAndPrependNode(value).setData(-1, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                cast(value, type);
            }
        }
    }

    private void parsePropertySpecifiers(Property property) throws TextSourceException {
        TextSource source = (TextSource) property.source;
        ClassType factEnclosing = property.parentType;
        ClassType realEnclosing = factEnclosing.getRealType();
        Method method = property.indexSynthetic;
        TypedMember indexMember = method;
        Constant indexConstant = null;
        Type typeInt = fldTypeInt;
        int indexPosition = 0;
        boolean hasIndex = method != null;
        /* index */
        label0: if(hasIndex)
        {
            int position = method.implementationPosition;
            Type targetType = method.type;
            Code code = method.code;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            indexPosition = position - 2;
            if(source.getLexemeKind(position) == L_NAME && source.getLexemeKind(position + 1) == COMMA)
            {
                String name = source.getLexemeString(position);
                Member member = factEnclosing.resolveName(name, factEnclosing, true);
                if(member instanceof Fieldoid)
                {
                    TypedMember[] foundFieldoids = factEnclosing.findFieldoids(name, factEnclosing);
                    int foundLength = foundFieldoids == null ? 0 : foundFieldoids.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"), new Object[] { factEnclosing.specialSimpleName, foundFieldoid }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name }
                        )) { source = source, position = position };
                    }
                    if(foundFieldoid instanceof Field)
                    {
                        Field foundField = (Field) foundFieldoid;
                        Type foundType = foundField.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.index.field-type"), new Object[] { foundField, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control);
                        if(!foundField.isStatic())
                        {
                            if(targetType.isAssignableFrom(foundType)) property.indexMember = indexMember = foundField;
                            value.setData(position, foundType, READ_FIELD, foundField);
                            code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        } else
                        {
                            switch(foundField.state)
                            {
                            case Field.COMPUTING:
                                throw new TextSourceException(String.format(
                                    package.getResourceString("field.self-dependent-value"), new Object[] { foundField }
                                )) { source = source, position = position };
                            case Field.NOT_COMPUTED:
                                parseStaticFieldValue(foundField, foundField.parentType.getStaticBlock());
                            }
                            Constant foundValue = foundField.value;
                            if(foundField.isFinal() && foundValue != null)
                            {
                                property.indexConstant = indexConstant = foundValue = foundValue.castTo(targetType);
                                value.setData(position, foundValue.type, LOAD_CONST, foundValue);
                            } else
                            {
                                value.setData(position, foundType, LOAD_STATIC, foundField);
                            }
                        }
                        cast(value, targetType);
                        break label0;
                    }
                    if(foundFieldoid instanceof Property)
                    {
                        Property foundProperty = (Property) foundFieldoid;
                        if(!foundProperty.hasRead())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.index.property-write-only"), new Object[] { foundProperty }
                            )) { source = source, position = position };
                        }
                        Type foundType = foundProperty.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.index.property-type"), new Object[] { foundProperty, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control).setData(position, foundType, READ_PROPERTY, foundProperty);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        cast(value, targetType);
                        break label0;
                    }
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                    )) { source = source, position = position };
                }
                if(member instanceof Method)
                {
                    Method[] foundMethods = factEnclosing.findMethods(name, null, factEnclosing);
                    int foundLength = foundMethods == null ? 0 : foundMethods.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.method"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    Method foundMethod = foundMethods[0];
                    if(foundMethod.isInterrupt())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.index.method-interrupt"), new Object[] { foundMethod }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isConvertableArguments(null))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.index.method-arguments"), new Object[] { foundMethod, ArgumentArray.toString(null) }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.method"), new Object[] { factEnclosing.specialSimpleName, foundMethod }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.method"), new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name + ArgumentArray.toString(null) }
                        )) { source = source, position = position };
                    }
                    Type foundType = foundMethod.type;
                    if(!targetType.isConvertableFrom(foundType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.index.method-return-type"), new Object[] { foundMethod, foundType, targetType }
                        )) { source = source, position = position };
                    }
                    ClassType foundThrowable = foundMethod.firstNonFreeThrowableType();
                    if(foundThrowable != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.index.method-throws"), new Object[] { foundMethod, foundThrowable }
                        )) { source = source, position = position };
                    }
                    Node value = code.createAndAppendNode(control);
                    if(foundMethod.isStatic())
                    {
                        value.setData(position, foundType, INVOKE_STATIC, foundMethod);
                    } else
                    {
                        if(targetType.isAssignableFrom(foundType)) property.indexMember = indexMember = foundMethod;
                        value.setData(position, foundType, invokeInstructionFor(foundMethod, factEnclosing), foundMethod);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                    }
                    cast(value, targetType);
                    break label0;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.member"), new Object[] { factEnclosing.specialSimpleName, name }
                )) { source = source, position = position };
            }
            if(source.getLexemeKind(position = parseExpression(control, source, position, false)) != COMMA)
            {
                throw new TextSourceException(package.getResourceString("expected.comma")) { source = source, position = position };
            }
            Node value = control[-1];
            requiresValue(value);
            Type valueType = value.type;
            if(!targetType.isConvertableFrom(valueType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("property.index.expression-type"), new Object[] { valueType, targetType }
                )) { source = source, position = position };
            }
            cast(value, targetType);
            if(value.instruction == LOAD_CONST) property.indexConstant = indexConstant = (Constant) value.operand1;
        }
        /* read */
        label0: if((method = property.readSynthetic) != null)
        {
            int kind;
            int position = method.implementationPosition;
            Type targetType = method.type;
            Code code = method.code;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(source.getLexemeKind(position) == L_NAME && ((kind = source.getLexemeKind(position + 1)) == COMMA || kind == CURLY_CLOSED))
            {
                String name = source.getLexemeString(position);
                Member member = factEnclosing.resolveName(name, factEnclosing, true);
                if(member instanceof Fieldoid)
                {
                    TypedMember[] foundFieldoids = factEnclosing.findFieldoids(name, factEnclosing);
                    int foundLength = foundFieldoids == null ? 0 : foundFieldoids.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"), new Object[] { factEnclosing.specialSimpleName, foundFieldoid }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name }
                        )) { source = source, position = position };
                    }
                    if(foundFieldoid instanceof Field)
                    {
                        Field foundField = (Field) foundFieldoid;
                        Type foundType = foundField.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.read.field-type"), new Object[] { foundField, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control);
                        if(!foundField.isStatic())
                        {
                            if(targetType.isAssignableFrom(foundType)) property.readMember = foundField;
                            value.setData(position, foundType, READ_FIELD, foundField);
                            code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        } else
                        {
                            switch(foundField.state)
                            {
                            case Field.COMPUTING:
                                throw new TextSourceException(String.format(
                                    package.getResourceString("field.self-dependent-value"), new Object[] { foundField }
                                )) { source = source, position = position };
                            case Field.NOT_COMPUTED:
                                parseStaticFieldValue(foundField, foundField.parentType.getStaticBlock());
                            }
                            Constant foundValue = foundField.value;
                            if(foundField.isFinal() && foundValue != null)
                            {
                                property.readConstant = foundValue = foundValue.castTo(targetType);
                                value.setData(position, foundValue.type, LOAD_CONST, foundValue);
                            } else
                            {
                                value.setData(position, foundType, LOAD_STATIC, foundField);
                            }
                        }
                        cast(value, targetType);
                        break label0;
                    }
                    if(foundFieldoid instanceof Property)
                    {
                        Property foundProperty = (Property) foundFieldoid;
                        if(!foundProperty.hasRead())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.read.property-write-only"), new Object[] { foundProperty }
                            )) { source = source, position = position };
                        }
                        Type foundType = foundProperty.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.read.property-type"), new Object[] { foundProperty, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control).setData(position, foundType, READ_PROPERTY, foundProperty);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        cast(value, targetType);
                        break label0;
                    }
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                    )) { source = source, position = position };
                }
                if(member instanceof Method)
                {
                    Type[] arguments = !hasIndex ? null : new Type[] { typeInt };
                    Method[] foundMethods = factEnclosing.findMethods(name, arguments, factEnclosing);
                    int foundLength = foundMethods == null ? 0 : foundMethods.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.method"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    Method foundMethod = foundMethods[0];
                    if(foundMethod.isInterrupt())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.read.method-interrupt"), new Object[] { foundMethod }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.read.method-arguments"), new Object[] { foundMethod, ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.method"), new Object[] { factEnclosing.specialSimpleName, foundMethod }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.method"),
                            new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name + ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    Type foundType = foundMethod.type;
                    if(!targetType.isConvertableFrom(foundType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.read.method-return-type"), new Object[] { foundMethod, foundType, targetType }
                        )) { source = source, position = position };
                    }
                    ClassType foundThrowable = foundMethod.firstNonFreeThrowableType();
                    if(foundThrowable != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.read.method-throws"), new Object[] { foundMethod, foundThrowable }
                        )) { source = source, position = position };
                    }
                    Node value = code.createAndAppendNode(control);
                    if(foundMethod.isStatic())
                    {
                        value.setData(position, foundType, INVOKE_STATIC, foundMethod);
                        if(hasIndex) appendPropertyIndexCode(position, value, indexConstant, indexMember);
                        for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(value[index], foundArguments[index].type);
                    } else
                    {
                        if(targetType.isAssignableFrom(foundType) && foundMethod.isAssignableArguments(arguments)) property.readMember = foundMethod;
                        value.setData(position, foundType, invokeInstructionFor(foundMethod, factEnclosing), foundMethod);
                        if(hasIndex) appendPropertyIndexCode(position, value, indexConstant, indexMember);
                        for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(value[index], foundArguments[index].type);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                    }
                    cast(value, targetType);
                    break label0;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.member"), new Object[] { factEnclosing.specialSimpleName, name }
                )) { source = source, position = position };
            }
            if(hasIndex)
            {
                Node index = code.createAndPrependNode(root).setData(-1, null, DECLARE_LOCAL, code.createLocal(true, typeInt, SPECNAME_INDEX, null, indexPosition));
                appendPropertyIndexCode(-1, index, indexConstant, indexMember);
            }
            if((kind = source.getLexemeKind(position = parseExpression(control, source, position, false))) != COMMA && kind != CURLY_CLOSED)
            {
                throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
            }
            Node value = control[-1];
            requiresValue(value);
            Type valueType = value.type;
            if(!targetType.isConvertableFrom(valueType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("property.read.expression-type"), new Object[] { valueType, targetType }
                )) { source = source, position = position };
            }
            cast(value, targetType);
            if(value.instruction == LOAD_CONST) property.readConstant = (Constant) value.operand1;
        }
        /* write */
        label0: if((method = property.writeSynthetic) != null)
        {
            int kind;
            int position = method.implementationPosition;
            Type sourceType = property.type;
            Code code = method.code;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node exit = code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(source.getLexemeKind(position) == L_NAME && ((kind = source.getLexemeKind(position + 1)) == COMMA || kind == CURLY_CLOSED))
            {
                Local value = method.getArgument(SPECNAME_VALUE);
                String name = source.getLexemeString(position);
                Member member = factEnclosing.resolveName(name, factEnclosing, true);
                if(member instanceof Fieldoid)
                {
                    TypedMember[] foundFieldoids = factEnclosing.findFieldoids(name, factEnclosing);
                    int foundLength = foundFieldoids == null ? 0 : foundFieldoids.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.member"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"), new Object[] { factEnclosing.specialSimpleName, foundFieldoid }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name }
                        )) { source = source, position = position };
                    }
                    if(foundFieldoid instanceof Field)
                    {
                        Field foundField = (Field) foundFieldoid;
                        if(foundField.isFinal())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.write.field-final"), new Object[] { foundField }
                            )) { source = source, position = position };
                        }
                        Type foundType = foundField.type;
                        if(!foundType.isConvertableFrom(sourceType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.write.field-type"), new Object[] { foundField, foundType, sourceType }
                            )) { source = source, position = position };
                        }
                        Node write = code.createAndPrependNode(root);
                        if(foundField.isStatic())
                        {
                            write.setData(position, null, STORE_STATIC, foundField);
                        } else
                        {
                            if(foundType.isAssignableFrom(sourceType)) property.writeMember = foundField;
                            write.setData(position, null, WRITE_FIELD, foundField);
                            code.createAndPrependNode(write).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        }
                        cast(code.createAndAppendNode(write).setData(position, value.type, LOAD_LOCAL, value), foundType);
                        break label0;
                    }
                    if(foundFieldoid instanceof Property)
                    {
                        Property foundProperty = (Property) foundFieldoid;
                        if(!foundProperty.hasWrite())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.write.property-read-only"), new Object[] { foundProperty }
                            )) { source = source, position = position };
                        }
                        Type foundType = foundProperty.type;
                        if(!foundType.isConvertableFrom(sourceType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.write.property-type"), new Object[] { foundProperty, foundType, sourceType }
                            )) { source = source, position = position };
                        }
                        Node write = code.createAndPrependNode(root).setData(position, null, WRITE_PROPERTY, foundProperty);
                        code.createAndPrependNode(write).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        cast(code.createAndAppendNode(write).setData(position, value.type, LOAD_LOCAL, value), foundType);
                        break label0;
                    }
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                    )) { source = source, position = position };
                }
                if(member instanceof Method)
                {
                    Type[] arguments = !hasIndex ? new Type[] { sourceType } : new Type[] { typeInt, sourceType };
                    Method[] foundMethods = factEnclosing.findMethods(name, arguments, factEnclosing);
                    int foundLength = foundMethods == null ? 0 : foundMethods.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.method"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    Method foundMethod = foundMethods[0];
                    if(foundMethod.isInterrupt())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.write.method-interrupt"), new Object[] { foundMethod }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.write.method-arguments"), new Object[] { foundMethod, ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.method"), new Object[] { factEnclosing.specialSimpleName, foundMethod }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.method"),
                            new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name + ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    Type foundType = foundMethod.type;
                    if(!foundType.isVoid())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.write.method-return-type"), new Object[] { foundMethod, foundType, fldTypeVoid }
                        )) { source = source, position = position };
                    }
                    ClassType foundThrowable = foundMethod.firstNonFreeThrowableType();
                    if(foundThrowable != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.write.method-throws"), new Object[] { foundMethod, foundThrowable }
                        )) { source = source, position = position };
                    }
                    if(foundMethod.isStatic())
                    {
                        Node write = code.createAndPrependNode(root).setData(position, null, INVOKE_STATIC, foundMethod);
                        if(hasIndex) appendPropertyIndexCode(position, write, indexConstant, indexMember);
                        code.createAndAppendNode(write).setData(position, value.type, LOAD_LOCAL, value);
                        for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(write[index], foundArguments[index].type);
                        break label0;
                    }
                    if(foundMethod.isAssignableArguments(arguments)) property.writeMember = foundMethod;
                    Node write = code.createAndPrependNode(root).setData(position, null, invokeInstructionFor(foundMethod, factEnclosing), foundMethod);
                    if(hasIndex) appendPropertyIndexCode(position, write, indexConstant, indexMember);
                    code.createAndAppendNode(write).setData(position, value.type, LOAD_LOCAL, value);
                    for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(write[index], foundArguments[index].type);
                    code.createAndPrependNode(write).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                    break label0;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.member"), new Object[] { factEnclosing.specialSimpleName, name }
                )) { source = source, position = position };
            }
            if(hasIndex)
            {
                Node index = code.createAndPrependNode(root).setData(-1, null, DECLARE_LOCAL, code.createLocal(true, typeInt, SPECNAME_INDEX, null, indexPosition));
                appendPropertyIndexCode(-1, index, indexConstant, indexMember);
            }
            if((kind = source.getLexemeKind(position = parseDeclareLocal(root, source, position, false))) != COMMA && kind != CURLY_CLOSED)
            {
                throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
            }
            code.moveNode(exit, root.length);
        }
        /* stored */
        label0: if((method = property.storedSynthetic) != null)
        {
            int position = method.implementationPosition;
            Type targetType = method.type;
            Code code = method.code;
            Node root = code.root.setData(-1, METHOD_ENTER, null);
            Node control = code.createAndAppendNode(root).setData(-1, RETURN);
            code.createAndAppendNode(root).setData(-1, METHOD_LEAVE);
            if(source.getLexemeKind(position) == L_NAME && source.getLexemeKind(position + 1) == CURLY_CLOSED)
            {
                String name = source.getLexemeString(position);
                Member member = factEnclosing.resolveName(name, factEnclosing, true);
                if(member instanceof Fieldoid)
                {
                    TypedMember[] foundFieldoids = factEnclosing.findFieldoids(name, factEnclosing);
                    int foundLength = foundFieldoids == null ? 0 : foundFieldoids.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"), new Object[] { factEnclosing.specialSimpleName, foundFieldoid }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name }
                        )) { source = source, position = position };
                    }
                    if(foundFieldoid instanceof Field)
                    {
                        Field foundField = (Field) foundFieldoid;
                        Type foundType = foundField.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.stored.field-type"), new Object[] { foundField, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control);
                        if(!foundField.isStatic())
                        {
                            if(targetType.isAssignableFrom(foundType)) property.storedMember = foundField;
                            value.setData(position, foundType, READ_FIELD, foundField);
                            code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        } else
                        {
                            switch(foundField.state)
                            {
                            case Field.COMPUTING:
                                throw new TextSourceException(String.format(
                                    package.getResourceString("field.self-dependent-value"), new Object[] { foundField }
                                )) { source = source, position = position };
                            case Field.NOT_COMPUTED:
                                parseStaticFieldValue(foundField, foundField.parentType.getStaticBlock());
                            }
                            Constant foundValue = foundField.value;
                            if(foundField.isFinal() && foundValue != null)
                            {
                                property.storedConstant = foundValue = foundValue.castTo(targetType);
                                value.setData(position, foundValue.type, LOAD_CONST, foundValue);
                            } else
                            {
                                value.setData(position, foundType, LOAD_STATIC, foundField);
                            }
                        }
                        cast(value, targetType);
                        break label0;
                    }
                    if(foundFieldoid instanceof Property)
                    {
                        Property foundProperty = (Property) foundFieldoid;
                        if(!foundProperty.hasRead())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.stored.property-write-only"), new Object[] { foundProperty }
                            )) { source = source, position = position };
                        }
                        Type foundType = foundProperty.type;
                        if(!targetType.isConvertableFrom(foundType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("property.stored.property-type"), new Object[] { foundProperty, foundType, targetType }
                            )) { source = source, position = position };
                        }
                        Node value = code.createAndAppendNode(control).setData(position, foundType, READ_PROPERTY, foundProperty);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                        cast(value, targetType);
                        break label0;
                    }
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { factEnclosing.specialSimpleName, name }
                    )) { source = source, position = position };
                }
                if(member instanceof Method)
                {
                    Type[] arguments = !hasIndex ? null : new Type[] { typeInt };
                    Method[] foundMethods = factEnclosing.findMethods(name, arguments, factEnclosing);
                    int foundLength = foundMethods == null ? 0 : foundMethods.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.method"), new Object[] { factEnclosing.specialSimpleName, name }
                        )) { source = source, position = position };
                    }
                    Method foundMethod = foundMethods[0];
                    if(foundMethod.isInterrupt())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.stored.method-interrupt"), new Object[] { foundMethod }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.stored.method-arguments"), new Object[] { foundMethod, ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    if(!foundMethod.isVisibleFrom(factEnclosing, factEnclosing))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.method"), new Object[] { factEnclosing.specialSimpleName, foundMethod }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.method"),
                            new Object[] { new StringBuilder(0x0400) + factEnclosing.specialCanonicalName + '.' + name + ArgumentArray.toString(arguments) }
                        )) { source = source, position = position };
                    }
                    Type foundType = foundMethod.type;
                    if(!targetType.isConvertableFrom(foundType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.stored.method-return-type"), new Object[] { foundMethod, foundType, targetType }
                        )) { source = source, position = position };
                    }
                    ClassType foundThrowable = foundMethod.firstNonFreeThrowableType();
                    if(foundThrowable != null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("property.stored.method-throws"), new Object[] { foundMethod, foundThrowable }
                        )) { source = source, position = position };
                    }
                    Node value = code.createAndAppendNode(control);
                    if(foundMethod.isStatic())
                    {
                        value.setData(position, foundType, INVOKE_STATIC, foundMethod);
                        if(hasIndex) appendPropertyIndexCode(position, value, indexConstant, indexMember);
                        for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(value[index], foundArguments[index].type);
                    } else
                    {
                        if(targetType.isAssignableFrom(foundType) && foundMethod.isAssignableArguments(arguments)) property.storedMember = foundMethod;
                        value.setData(position, foundType, invokeInstructionFor(foundMethod, factEnclosing), foundMethod);
                        if(hasIndex) appendPropertyIndexCode(position, value, indexConstant, indexMember);
                        for(ArgumentArray foundArguments = foundMethod.arguments, int index = foundArguments.length; index-- > 0; ) cast(value[index], foundArguments[index].type);
                        code.createAndPrependNode(value).setData(position, realEnclosing, LOAD_LOCAL, method.arguments.thisArgument);
                    }
                    cast(value, targetType);
                    break label0;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.member"), new Object[] { factEnclosing.specialSimpleName, name }
                )) { source = source, position = position };
            }
            if(hasIndex)
            {
                Node index = code.createAndPrependNode(root).setData(-1, null, DECLARE_LOCAL, code.createLocal(true, typeInt, SPECNAME_INDEX, null, indexPosition));
                appendPropertyIndexCode(-1, index, indexConstant, indexMember);
            }
            if(source.getLexemeKind(position = parseExpression(control, source, position, false)) != CURLY_CLOSED)
            {
                throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
            }
            Node value = control[-1];
            requiresValue(value);
            Type valueType = value.type;
            if(!targetType.isConvertableFrom(valueType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("property.stored.expression-type"), new Object[] { valueType, targetType }
                )) { source = source, position = position };
            }
            cast(value, targetType);
            if(value.instruction == LOAD_CONST) property.storedConstant = (Constant) value.operand1;
        }
    }

    private void parseStaticFieldValue(Field field, ClassInit staticBlock) throws TextSourceException {
        if(field.state == Field.NOT_COMPUTED)
        {
            TextSource source = (TextSource) field.source;
            int position = field.implementationPosition;
            switch(source.getLexemeKind(position))
            {
            case SEMICOLON:
                field.closeComputing();
                break;
            case EQUALS:
                if(field.isStatic())
                {
                    Code code = staticBlock.code;
                    field.openComputing();
                    try
                    {
                        int before = position;
                        Node store = code.createAndAppendNode(null);
                        if(source.getLexemeKind(position = parseExpression(store, source, position + 1, false)) != SEMICOLON)
                        {
                            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
                        }
                        Node value = store[-1];
                        requiresValue(value);
                        Type fieldType = field.type;
                        Type valueType = value.type;
                        if(!fieldType.isConvertableFrom(valueType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, fieldType }
                            )) { source = source, position = position };
                        }
                        if((value = cast(value, fieldType)).instruction != LOAD_CONST || !fieldType.isPrimitive() && !field.isFinal())
                        {
                            store.setData(before, null, STORE_STATIC, field);
                        } else
                        {
                            field.setComputedValue((Constant) value.operand1);
                            code.removeNode(store);
                        }
                    } finally
                    {
                        field.closeComputing();
                    }
                    break;
                }
                /* падение через */
            default:
                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
            }
        }
    }

    private int parsePostfix(Node parent, TextSource source, int position, boolean isStaticOnly, boolean isImplicitPeriod) throws TextSourceException {
        Code code = parent.parentCode;
        Callable enclosingCallable = code.parentCallable;
        ClassType enclosingClassType = enclosingCallable.parentType;
        label0: for(Node child1 = parent[-1], boolean isUseSuper = child1.useSuper; ; isImplicitPeriod = isUseSuper = false, position++)
        {
            int operation = source.getLexemeKind(position);
            if(isUseSuper && operation != PERIOD && operation != PARENTH_OPENED && operation != BRACKET_OPENED)
            {
                throw new TextSourceException(package.getResourceString("error.expression.super")) { source = source, position = position };
            }
            boolean isPeriod = false;
            if(isImplicitPeriod)
            {
                isPeriod = true;
            }
            else if(operation == PERIOD)
            {
                isPeriod = true;
                position++;
            }
            int before = position;
            Type argument1Type = child1.type;
            if(isPeriod)
            {
                if(argument1Type != null && !(argument1Type instanceof ClassType))
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.dereference.type"), new Object[] { argument1Type }
                    )) { source = source, position = position };
                }
                int context;
                ClassType dereferenceClassType;
                if(child1.instruction == CLASS)
                {
                    context = -1; /* это точно статичный контекст */
                    dereferenceClassType = (ClassType) child1.operand1;
                } else
                {
                    context = isImplicitPeriod ? 0 /* неопределённый контекст */ : 1 /* это точно инстанционный контекст */;
                    dereferenceClassType = (ClassType) argument1Type;
                }
                int kind = 0;
                String name = null;
                switch(source.getLexemeKind(position))
                {
                case OPERATOR:
                    ImmediateBuilderItemHolder operatorHolder = getItemHolder();
                    position = parseOperator(source, position + 1, operatorHolder) - 1;
                    kind = operatorHolder.resultKind;
                    name = Operator.kindToSpecialSimpleName(kind);
                    break;
                case L_NAME:
                    name = source.getLexemeString(position);
                    break;
                default:
                    throw new TextSourceException(package.getResourceString("expected.name.member")) { source = source, position = position };
                }
                Member resolvedMember = dereferenceClassType.resolveName(name, enclosingClassType, false);
                if(resolvedMember instanceof Fieldoid)
                {
                    TypedMember[] foundFieldoids = dereferenceClassType.findFieldoids(name, enclosingClassType);
                    int foundLength = foundFieldoids == null ? 0 : foundFieldoids.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { dereferenceClassType, name }
                        )) { source = source, position = before };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"),
                            new Object[] { enclosingClassType.specialSimpleName, foundFieldoid }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + dereferenceClassType.specialCanonicalName + '.' + name }
                        )) { source = source, position = before };
                    }
                    if(foundFieldoid instanceof Field)
                    {
                        Field foundField = (Field) foundFieldoid;
                        if(context > 0)
                        {
                            if(foundField.isStatic())
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("must-be.access.static-field"), new Object[] { foundField }
                                )) { source = source, position = before };
                            }
                            Node result = code.createAndAppendNode(parent).setData(before, foundField.type, READ_FIELD, foundField);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        if(!foundField.isStatic())
                        {
                            if(context < 0)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("must-be.access.instance-field"), new Object[] { foundField }
                                )) { source = source, position = before };
                            }
                            Node result = code.createAndAppendNode(parent).setData(before, foundField.type, READ_FIELD, foundField);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        switch(foundField.state)
                        {
                        case Field.COMPUTING:
                            throw new TextSourceException(String.format(
                                package.getResourceString("field.self-dependent-value"), new Object[] { foundField }
                            )) { source = source, position = before };
                        case Field.NOT_COMPUTED:
                            parseStaticFieldValue(foundField, foundField.parentType.getStaticBlock());
                        }
                        Constant foundValue = foundField.value;
                        if(foundField.isFinal() && foundValue != null)
                        {
                            child1.setData(before, foundValue.type, LOAD_CONST, foundValue);
                            continue;
                        }
                        child1.setData(before, foundField.type, LOAD_STATIC, foundField);
                        continue;
                    }
                    if(foundFieldoid instanceof Property)
                    {
                        Property foundProperty = (Property) foundFieldoid;
                        if(context < 0)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("must-be.access.property"), new Object[] { foundProperty }
                            )) { source = source, position = before };
                        }
                        Node result = code.createAndAppendNode(parent);
                        if(foundProperty.hasRead())
                        {
                            if(isUseSuper)
                            {
                                if(foundProperty.isAbstract())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.direct-access-abstract.property.read"), new Object[] { foundProperty }
                                    )) { source = source, position = before };
                                }
                                result.setData(before, foundProperty.type, READ_SPECIAL, foundProperty);
                            } else
                            {
                                result.setData(before, foundProperty.type, READ_PROPERTY, foundProperty);
                            }
                        } else
                        {
                            if(source.getLexemeKind(position + 1) != EQUALS)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.access.property-write-only.read"), new Object[] { foundProperty }
                                )) { source = source, position = before };
                            }
                            if(isUseSuper)
                            {
                                if(foundProperty.isAbstract())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.direct-access-abstract.property.write"), new Object[] { foundProperty }
                                    )) { source = source, position = before };
                                }
                                result.setData(before, foundProperty.type, WRITE_SPECIAL, foundProperty);
                            } else
                            {
                                result.setData(before, foundProperty.type, WRITE_PROPERTY, foundProperty);
                            }
                        }
                        code.moveNode(child1, child1 = result, 0);
                        continue;
                    }
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { dereferenceClassType, name }
                    )) { source = source, position = before };
                }
                if(resolvedMember instanceof Callable)
                {
                    if(source.getLexemeKind(position + 1) != PARENTH_OPENED)
                    {
                        if(kind != 0)
                        {
                            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position + 1 };
                        }
                        Callable[] foundInterrupts = dereferenceClassType.findInterrupts(name, enclosingClassType);
                        int foundLength = foundInterrupts == null ? 0 : foundInterrupts.length;
                        if(foundLength < 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.converted.interrupt"), new Object[] { dereferenceClassType, name }
                            )) { source = source, position = before };
                        }
                        Callable foundInterrupt = foundInterrupts[0];
                        if(!foundInterrupt.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.interrupt"), new Object[] { enclosingClassType.specialSimpleName, foundInterrupt }
                            )) { source = source, position = before };
                        }
                        if(foundLength > 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("ambiguous.interrupt"), new Object[] { new StringBuilder(0x0400) + dereferenceClassType.specialCanonicalName + '.' + name }
                            )) { source = source, position = before };
                        }
                        if(context > 0)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("must-be.access.static-method"), new Object[] { foundInterrupt }
                            )) { source = source, position = before };
                        }
                        child1.setData(before, fldTypeLong, LOAD_INTERRUPT, foundInterrupt);
                        continue;
                    }
                    Node result = code.createAndAppendNode(parent);
                    label1: if(source.getLexemeKind(position += 2) != PARENTH_CLOSED) do
                    {
                        position = parseExpression(result, source, position, isStaticOnly);
                        requiresValue(result[-1]);
                        switch(source.getLexemeKind(position))
                        {
                        default:
                            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                        case PARENTH_CLOSED:
                            break label1;
                        case COMMA:
                            position++;
                        }
                    } while(true);
                    int length = result.length;
                    Type[] arguments = new Type[length];
                    for(int index = 0; index < length; index++) arguments[index] = result[index].type;
                    Callable[] foundCallables = kind != 0 ? (
                        (Callable[]) dereferenceClassType.findOperators(kind, arguments, enclosingClassType)
                    ) : (
                        (Callable[]) dereferenceClassType.findMethods(name, arguments, enclosingClassType)
                    );
                    int foundLength = foundCallables == null ? 0 : foundCallables.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(kind != 0 ? String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(kind) }
                        ) : String.format(
                            package.getResourceString("can-not-be.converted.method"), new Object[] { dereferenceClassType, name }
                        )) { source = source, position = before };
                    }
                    Callable foundCallable = foundCallables[0];
                    if(foundCallable.isInterrupt())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.invoke-interrupt"), new Object[] { foundCallable }
                        )) { source = source, position = before };
                    }
                    if(!foundCallable.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(kind != 0 ? "not-applicable.operator" : "not-applicable.method"), new Object[] { foundCallable, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundCallable.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(kind != 0 ? "invisible.operator" : "invisible.method"), new Object[] { enclosingClassType.specialSimpleName, foundCallable }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(kind != 0 ? String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(kind) + foundCallable.arguments }
                        ) : String.format(
                            package.getResourceString("ambiguous.method"), new Object[] { new StringBuilder(0x0400) + dereferenceClassType + '.' + name + foundCallable.arguments }
                        )) { source = source, position = before };
                    }
                    if(isUseSuper && foundCallable.isAbstract())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(kind > 0 ? "can-not-be.direct-access-abstract.operator" : "can-not-be.direct-access-abstract.method"), new Object[] { foundCallable }
                        )) { source = source, position = before };
                    }
                    for(ArgumentArray foundArguments = foundCallable.arguments, int index = 0; index < length; index++)
                    {
                        cast(result[index], foundArguments[index].type);
                    }
                    if(context < 0)
                    {
                        if(!foundCallable.isStatic())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString(kind != 0 ? "must-be.access.operator" : "must-be.access.instance-method"), new Object[] { foundCallable }
                            )) { source = source, position = before };
                        }
                        result.setData(before, foundCallable.type, INVOKE_STATIC, foundCallable);
                        code.removeNode(child1);
                        child1 = result;
                        continue;
                    }
                    if(foundCallable.isStatic())
                    {
                        if(context > 0)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("must-be.access.static-method"), new Object[] { foundCallable }
                            )) { source = source, position = before };
                        }
                        result.setData(before, foundCallable.type, INVOKE_STATIC, foundCallable);
                        code.removeNode(child1);
                        child1 = result;
                        continue;
                    }
                    result.setData(before, foundCallable.type, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundCallable, dereferenceClassType), foundCallable);
                    code.moveNode(child1, child1 = result, 0);
                    continue;
                }
                throw new TextSourceException(kind > 0 ? String.format(
                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(kind) }
                ) : String.format(
                    package.getResourceString("can-not-be.converted.member"), new Object[] { dereferenceClassType, name }
                )) { source = source, position = before };
            }
            switch(operation)
            {
            case PARENTH_OPENED:
                if(argument1Type instanceof ClassType)
                {
                    Node result = code.createAndAppendNode(parent);
                    ClassType dereferenceClassType = (ClassType) argument1Type;
                    label1: if(source.getLexemeKind(++position) != PARENTH_CLOSED) do
                    {
                        position = parseExpression(result, source, position, isStaticOnly);
                        requiresValue(result[-1]);
                        switch(source.getLexemeKind(position))
                        {
                        default:
                            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                        case PARENTH_CLOSED:
                            break label1;
                        case COMMA:
                            position++;
                        }
                    } while(true);
                    int length = result.length;
                    Type[] arguments = new Type[length];
                    for(int index = 0; index < length; index++) arguments[index] = result[index].type;
                    Operator[] foundOperators = dereferenceClassType.findOperators(INVOKE_VIRTUAL, arguments, enclosingClassType);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(INVOKE_VIRTUAL) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(INVOKE_VIRTUAL) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    if(isUseSuper && foundOperator.isAbstract())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundOperator }
                        )) { source = source, position = before };
                    }
                    for(ArgumentArray foundArguments = foundOperator.arguments, int index = 0; index < length; index++) cast(result[index], foundArguments[index].type);
                    result.setData(-1, foundOperator.type, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.moveNode(child1, child1 = result, 0);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("operator.not-applicable-to-type"), new Object[] { argument1Type, Operator.kindToSymbol(INVOKE_VIRTUAL) }
                )) { source = source, position = before };
            case BRACKET_OPENED:
                if(argument1Type instanceof PrimitiveType && argument1Type.isVector())
                {
                    PrimitiveType typeInt = fldTypeInt;
                    PrimitiveType vectorMainType = (PrimitiveType) argument1Type;
                    PrimitiveType vectorBaseType = vectorMainType.vectorBaseType;
                    if(source.getLexemeKind(position = parseExpression(parent, source, position + 1, isStaticOnly)) != BRACKET_CLOSED)
                    {
                        throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
                    }
                    Node child2 = parent[-1];
                    requiresValue(child2);
                    Type argument2Type = child2.type;
                    if(!typeInt.isConvertableFrom(argument2Type))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { argument2Type, typeInt }
                        )) { source = source, position = position };
                    }
                    child2 = cast(child2, typeInt);
                    if(child2.instruction == LOAD_CONST)
                    {
                        int index = ((Constant) child2.operand1).asInt();
                        if(index < 0 || index >= vectorMainType.vectorLength)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("out-of-range.vector-index"), new Object[] { Int.toString(index) }
                            )) { source = source, position = position };
                        }
                        if(child1.instruction == LOAD_CONST)
                        {
                            switch(vectorBaseType.kind >> 2)
                            {
                            case DOUBLE >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createDouble(((Constant) child1.operand1).asDouble8()[index]));
                                break;
                            case FLOAT >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createFloat(((Constant) child1.operand1).asFloat8()[index]));
                                break;
                            case BYTE >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createByte(((Constant) child1.operand1).asByte8()[index]));
                                break;
                            case SHORT >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createShort(((Constant) child1.operand1).asShort8()[index]));
                                break;
                            case INT >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createInt(((Constant) child1.operand1).asInt8()[index]));
                                break;
                            case LONG >> 2:
                                child1.setData(child1.position, vectorBaseType, LOAD_CONST, fldConstantFactory.createLong(((Constant) child1.operand1).asLong8()[index]));
                            }
                            code.removeNode(child2);
                            continue;
                        }
                    }
                    Node result = code.createAndAppendNode(parent).setData(-1, vectorBaseType, READ_ELEMENT, vectorMainType);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                if(argument1Type instanceof ArrayType)
                {
                    PrimitiveType typeInt = fldTypeInt;
                    Type componentType = ((ArrayType) argument1Type).componentType;
                    if(source.getLexemeKind(position = parseExpression(parent, source, position + 1, isStaticOnly)) != BRACKET_CLOSED)
                    {
                        throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
                    }
                    Node child2 = parent[-1];
                    requiresValue(child2);
                    Type argument2Type = child2.type;
                    if(!typeInt.isConvertableFrom(argument2Type))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { argument2Type, typeInt }
                        )) { source = source, position = position };
                    }
                    child2 = cast(child2, typeInt);
                    Node result = code.createAndAppendNode(parent).setData(-1, componentType, READ_COMPONENT, componentType);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                if(argument1Type instanceof ClassType)
                {
                    ClassType dereferenceClassType = (ClassType) argument1Type;
                    if(source.getLexemeKind(position = parseExpression(parent, source, position + 1, isStaticOnly)) != BRACKET_CLOSED)
                    {
                        throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
                    }
                    Node child2 = parent[-1];
                    requiresValue(child2);
                    Node result = code.createAndAppendNode(parent);
                    if(source.getLexemeKind(position + 1) == EQUALS)
                    {
                        result.setData(-1, null, INVOKE_VIRTUAL, null);
                    } else
                    {
                        Type[] arguments = new Type[] { child2.type };
                        Operator[] foundOperators = dereferenceClassType.findOperators(READ_COMPONENT, arguments, enclosingClassType);
                        int foundLength = foundOperators == null ? 0 : foundOperators.length;
                        if(foundLength < 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(READ_COMPONENT) }
                            )) { source = source, position = before };
                        }
                        Operator foundOperator = foundOperators[0];
                        if(!foundOperator.isConvertableArguments(arguments))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                            )) { source = source, position = before };
                        }
                        if(!foundOperator.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundOperator }
                            )) { source = source, position = before };
                        }
                        if(foundLength > 1)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("ambiguous.operator"),
                                new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(READ_COMPONENT) + foundOperator.arguments }
                            )) { source = source, position = before };
                        }
                        if(isUseSuper && foundOperator.isAbstract())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundOperator }
                            )) { source = source, position = before };
                        }
                        child2 = cast(child2, foundOperator.arguments[0].type);
                        result.setData(-1, foundOperator.type, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    }
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("operator.not-applicable-to-type"), new Object[] { argument1Type, Operator.kindToSymbol(READ_COMPONENT) }
                )) { source = source, position = before };
            case INC_LOCAL:
            case DEC_LOCAL:
                int instruction = child1.instruction;
                switch(instruction)
                {
                case LOAD_LOCAL:
                    {
                        Local foundLocal = (Local) child1.operand1;
                        if(foundLocal.isFinal())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.local-final.write"), new Object[] { foundLocal }
                            )) { source = source, position = before };
                        }
                        if(!((argument1Type = foundLocal.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                            )) { source = source, position = before };
                        }
                        child1.setData(child1.position, argument1Type, operation == INC_LOCAL ? INC_POST_LOAD_LOCAL : DEC_POST_LOAD_LOCAL, foundLocal);
                        continue;
                    }
                case LOAD_STATIC:
                    {
                        Field foundField = (Field) child1.operand1;
                        if(foundField.isFinal() && (!(enclosingCallable instanceof ClassInit) || foundField.parentType != enclosingClassType || foundField.value != null))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundField }
                            )) { source = source, position = before };
                        }
                        if(!((argument1Type = foundField.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                            )) { source = source, position = before };
                        }
                        code.createAndAppendNode(child1).setData(child1.position, argument1Type, LOAD_STATIC, foundField);
                        Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                        code.createAndPrependNode(delta).setData(-1, null, DUP1, argument1Type);
                        child1.setData(-1, argument1Type, STORE_STATIC, foundField);
                        continue;
                    }
                case READ_FIELD:
                case READ_SPECIAL:
                case READ_PROPERTY:
                    {
                        TypedMember foundFieldoid = (TypedMember) child1.operand1;
                        if(foundFieldoid instanceof Property)
                        {
                            if(!((Property) foundFieldoid).hasWrite())
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.access.property-read-only.write"), new Object[] { foundFieldoid }
                                )) { source = source, position = before };
                            }
                        } else
                        {
                            Node load = child1[0];
                            if(
                                foundFieldoid.isFinal() && (
                                    !(enclosingCallable instanceof InstInit) || foundFieldoid.parentType != enclosingClassType ||
                                    load.instruction != LOAD_LOCAL || load.operand1 != enclosingCallable.arguments.thisArgument
                                )
                            )
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundFieldoid }
                                )) { source = source, position = before };
                            }
                        }
                        if(!((argument1Type = foundFieldoid.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                            )) { source = source, position = before };
                        }
                        Node read = code.createAndAppendNode(child1).setData(child1.position, argument1Type, instruction, foundFieldoid);
                        code.createAndAppendNode(read).setData(-1, null, DUP1, fldTypeObject);
                        Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                        code.createAndPrependNode(delta).setData(-1, null, DUP1X1, argument1Type);
                        child1.setData(-1, argument1Type, instruction + A_DELTA, foundFieldoid);
                        continue;
                    }
                case READ_COMPONENT:
                    {
                        if(!((argument1Type = (Type) child1.operand1) instanceof PrimitiveType) || !argument1Type.isNumeric())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                            )) { source = source, position = before };
                        }
                        Node read = code.createAndAppendNode(child1).setData(child1.position, argument1Type, READ_COMPONENT, argument1Type);
                        code.createAndAppendNode(read).setData(-1, null, DUP2, fldTypeInt);
                        Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                        code.createAndPrependNode(delta).setData(-1, null, DUP1X2, argument1Type);
                        child1.setData(-1, argument1Type, WRITE_COMPONENT, argument1Type);
                        continue;
                    }
                case INVOKE_SERVICE:
                case INVOKE_SPECIAL:
                case INVOKE_VIRTUAL:
                    Operator foundReadOperator;
                    TableItem foundCallable = child1.operand1;
                    if(foundCallable instanceof Operator && (foundReadOperator = (Operator) foundCallable).kind == READ_COMPONENT)
                    {
                        if(!((argument1Type = foundReadOperator.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                            )) { source = source, position = before };
                        }
                        Node load = child1[0];
                        ClassType dereferenceClassType = (ClassType) load.type;
                        Type[] arguments = new Type[] { foundReadOperator.arguments[0].type, argument1Type };
                        Operator[] foundOperators = dereferenceClassType.findOperators(WRITE_COMPONENT, arguments, enclosingClassType);
                        Operator foundWriteOperator = foundOperators == null || foundOperators.length != 1 ? null : foundOperators[0];
                        if(foundWriteOperator == null || !foundWriteOperator.isIdentityArguments(arguments))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-found.operator"), new Object[] { dereferenceClassType, Operator.kindToSymbol(WRITE_COMPONENT) + ArgumentArray.toString(arguments) }
                            )) { source = source, position = before };
                        }
                        if(!foundWriteOperator.isVisibleFrom(enclosingClassType, (isUseSuper = load.useSuper) ? enclosingClassType : dereferenceClassType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundWriteOperator }
                            )) { source = source, position = before };
                        }
                        if(isUseSuper && foundWriteOperator.isAbstract())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundWriteOperator }
                            )) { source = source, position = before };
                        }
                        Node read = code.createAndAppendNode(child1).setData(child1.position, argument1Type, instruction, foundReadOperator);
                        code.createAndAppendNode(read).setData(-1, null, DUP2, arguments[0]);
                        Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                        code.createAndPrependNode(delta).setData(-1, null, DUP1X2, argument1Type);
                        child1.setData(-1, argument1Type, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundWriteOperator, dereferenceClassType), foundWriteOperator);
                        continue;
                    }
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("applicable.operator.increment-decrement"), new Object[] { source.getLexemeString(before) }
                )) { source = source, position = before };
            default:
                break label0;
            }
        }
        return position;
    }

    private int parsePrimary(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        boolean isImplicitPeriod = false;
        int operation = source.getLexemeKind(position);
        Code code = parent.parentCode;
        Callable enclosingCallable = code.parentCallable;
        ClassType enclosingClassType = enclosingCallable.parentType;
        label0: switch(operation)
        {
        case PARENTH_OPENED:
            {
                if(source.getLexemeKind(position = parseExpression(parent, source, position + 1, isStaticOnly)) != PARENTH_CLOSED)
                {
                    throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                }
                requiresValue(parent[-1]);
                break;
            }
        case SUPER:
            {
                if(isStaticOnly)
                {
                    throw new TextSourceException(package.getResourceString("can-not-reference.this")) { source = source, position = position };
                }
                if(enclosingCallable.isStatic())
                {
                    throw new TextSourceException(package.getResourceString("can-not-use.static.this")) { source = source, position = position };
                }
                if(enclosingClassType.isHelper())
                {
                    throw new TextSourceException(package.getResourceString("can-not-use.helper.super")) { source = source, position = position };
                }
                ClassType foundClassType = enclosingClassType.getSuperclassType();
                if(foundClassType == null)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-use.super"), new Object[] { enclosingClassType.specialSimpleName }
                    )) { source = source, position = position };
                }
                code.createAndAppendNode(parent).setData(position, foundClassType, LOAD_LOCAL, enclosingCallable.arguments.thisArgument).useSuper = true;
                break;
            }
        case THIS:
            {
                if(isStaticOnly)
                {
                    throw new TextSourceException(package.getResourceString("can-not-reference.this")) { source = source, position = position };
                }
                if(enclosingCallable.isStatic())
                {
                    throw new TextSourceException(package.getResourceString("can-not-use.static.this")) { source = source, position = position };
                }
                code.createAndAppendNode(parent).setData(position, enclosingClassType.getRealType(), LOAD_LOCAL, enclosingCallable.arguments.thisArgument);
                break;
            }
        case NEW:
            int before = position++;
            ImmediateBuilderItemHolder resultTypeHolder = getItemHolder();
            position = parseTypeName(source, position, enclosingClassType, resultTypeHolder);
            Type resultType = resultTypeHolder.resultType;
            if(resultType instanceof ArrayType)
            {
                if(source.getLexemeKind(position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                resultType.makeCompilable();
                Node result = code.createAndAppendNode(parent);
                ConstantFactory factory = fldConstantFactory;
                label1: if(source.getLexemeKind(++position) != CURLY_CLOSED) for(Type componentType = ((ArrayType) resultType).componentType, Type typeInt = fldTypeInt, int index = 0; ; index++)
                {
                    Node write = code.createAndAppendNode(result).setData(-1, null, WRITE_COMPONENT, componentType);
                    code.createAndAppendNode(write).setData(position, resultType, DUP1, resultType);
                    code.createAndAppendNode(write).setData(-1, typeInt, LOAD_CONST, factory.createInt(index));
                    position = parseExpression(write, source, position, isStaticOnly);
                    Node value = write[-1];
                    requiresValue(value);
                    Type valueType = value.type;
                    if(!componentType.isConvertableFrom(valueType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, componentType }
                        )) { source = source, position = position };
                    }
                    cast(value, componentType);
                    switch(source.getLexemeKind(position))
                    {
                    default:
                        throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
                    case CURLY_CLOSED:
                        break label1;
                    case COMMA:
                        position++;
                    }
                }
                for(int index = result.length, result.setData(before, resultType, NEW_ARRAY, resultType, factory.createInt(index)); index-- > 0; )
                {
                    Node write = result[index];
                    Node value = write[-1];
                    TableItem operand = value.operand1;
                    if(value.instruction == LOAD_CONST && ((Constant) operand).isDefaultValue()) code.removeNode(write);
                }
                break;
            }
            if(source.getLexemeKind(position) == BRACKET_OPENED)
            {
                if(resultType.isVoid())
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("type.not-suitable.array-components"), new Object[] { resultType }
                    )) { source = source, position = position };
                }
                int dimCountCreate = 0;
                Type typeInt = fldTypeInt;
                Node result = code.createAndAppendNode(parent);
                do
                {
                    dimCountCreate++;
                    if(source.getLexemeKind(position = parseExpression(result, source, position + 1, isStaticOnly)) != BRACKET_CLOSED)
                    {
                        throw new TextSourceException(package.getResourceString("expected.closed-bracket")) { source = source, position = position };
                    }
                    Node value = result[-1];
                    requiresValue(value);
                    Type valueType = value.type;
                    if(!typeInt.isConvertableFrom(valueType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, typeInt }
                        )) { source = source, position = position };
                    }
                    cast(value, typeInt);
                    if(dimCountCreate >= LIMIT_DIMENSIONS_COUNT || source.getLexemeKind(position + 1) != BRACKET_OPENED || source.getLexemeKind(position + 2) == BRACKET_CLOSED) break;
                    position++;
                } while(true);
                int dimCountTotal = dimCountCreate;
                for(; dimCountTotal < LIMIT_DIMENSIONS_COUNT && source.getLexemeKind(position + 1) == BRACKET_OPENED && source.getLexemeKind(position + 2) == BRACKET_CLOSED; dimCountTotal++)
                {
                    position += 2;
                }
                (resultType = acquireArrayType(resultType, dimCountTotal)).makeCompilable();
                if(dimCountCreate <= 1)
                {
                    result.setData(before, resultType, NEW_ARRAY_MONO, resultType);
                } else
                {
                    result.setData(before, resultType, NEW_ARRAY_MULTI, resultType);
                    Type typeInt01d = getArrayType(typeInt);
                    typeInt01d.makeCompilable();
                    ConstantFactory factory = fldConstantFactory;
                    Node array = code.createAndAppendNode(result).setData(before, typeInt01d, NEW_ARRAY, typeInt01d, factory.createInt(dimCountCreate));
                    for(int index = dimCountCreate; index-- > 0; )
                    {
                        Node value = result[index];
                        Node write = code.createAndPrependNode(array).setData(-1, null, WRITE_COMPONENT, typeInt);
                        code.createAndAppendNode(write).setData(-1, typeInt01d, DUP1, typeInt01d);
                        code.createAndAppendNode(write).setData(-1, typeInt, LOAD_CONST, factory.createInt(index));
                        code.moveNode(value, write, 2);
                    }
                }
                break;
            }
            if(resultType instanceof PrimitiveType && resultType.isVector())
            {
                if(source.getLexemeKind(position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                boolean isConstant = true;
                Node result = code.createAndAppendNode(parent);
                PrimitiveType vectorResultType = (PrimitiveType) resultType;
                PrimitiveType vectorBaseType = vectorResultType.vectorBaseType;
                int vectorResultLength = vectorResultType.vectorLength;
                for(int index = 0; ; )
                {
                    position = parseExpression(result, source, position + 1, isStaticOnly);
                    Node value = result[-1];
                    requiresValue(value);
                    Type valueType = value.type;
                    if(!vectorBaseType.isConvertableFrom(valueType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, vectorBaseType }
                        )) { source = source, position = position };
                    }
                    if(cast(value, vectorBaseType).instruction != LOAD_CONST)
                    {
                        isConstant = false;
                    }
                    if(++index >= vectorResultLength)
                    {
                        break;
                    }
                    if(source.getLexemeKind(position) != COMMA)
                    {
                        throw new TextSourceException(package.getResourceString("expected.comma")) { source = source, position = position };
                    }
                }
                if(source.getLexemeKind(position) != CURLY_CLOSED)
                {
                    throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
                }
                if(!isConstant)
                {
                    result.setData(before, resultType, NEW_VECTOR, resultType);
                } else
                {
                    switch(vectorResultType.kind)
                    {
                    case DOUBLE2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createDouble2(new double2 {
                            ((Constant) result[0].operand1).asDouble(), ((Constant) result[1].operand1).asDouble()
                        }));
                        break;
                    case DOUBLE4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createDouble4(new double4 {
                            ((Constant) result[0].operand1).asDouble(), ((Constant) result[1].operand1).asDouble(),
                            ((Constant) result[2].operand1).asDouble(), ((Constant) result[3].operand1).asDouble()
                        }));
                        break;
                    case DOUBLE8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createDouble8(new double8 {
                            ((Constant) result[0].operand1).asDouble(), ((Constant) result[1].operand1).asDouble(),
                            ((Constant) result[2].operand1).asDouble(), ((Constant) result[3].operand1).asDouble(),
                            ((Constant) result[4].operand1).asDouble(), ((Constant) result[5].operand1).asDouble(),
                            ((Constant) result[6].operand1).asDouble(), ((Constant) result[7].operand1).asDouble()
                        }));
                        break;
                    case FLOAT2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createFloat2(new float2 {
                            ((Constant) result[0].operand1).asFloat(), ((Constant) result[1].operand1).asFloat()
                        }));
                        break;
                    case FLOAT4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createFloat4(new float4 {
                            ((Constant) result[0].operand1).asFloat(), ((Constant) result[1].operand1).asFloat(),
                            ((Constant) result[2].operand1).asFloat(), ((Constant) result[3].operand1).asFloat()
                        }));
                        break;
                    case FLOAT8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createFloat8(new float8 {
                            ((Constant) result[0].operand1).asFloat(), ((Constant) result[1].operand1).asFloat(),
                            ((Constant) result[2].operand1).asFloat(), ((Constant) result[3].operand1).asFloat(),
                            ((Constant) result[4].operand1).asFloat(), ((Constant) result[5].operand1).asFloat(),
                            ((Constant) result[6].operand1).asFloat(), ((Constant) result[7].operand1).asFloat()
                        }));
                        break;
                    case BYTE2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createByte2(new byte2 {
                            ((Constant) result[0].operand1).asByte(), ((Constant) result[1].operand1).asByte()
                        }));
                        break;
                    case BYTE4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createByte4(new byte4 {
                            ((Constant) result[0].operand1).asByte(), ((Constant) result[1].operand1).asByte(),
                            ((Constant) result[2].operand1).asByte(), ((Constant) result[3].operand1).asByte()
                        }));
                        break;
                    case BYTE8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createByte8(new byte8 {
                            ((Constant) result[0].operand1).asByte(), ((Constant) result[1].operand1).asByte(),
                            ((Constant) result[2].operand1).asByte(), ((Constant) result[3].operand1).asByte(),
                            ((Constant) result[4].operand1).asByte(), ((Constant) result[5].operand1).asByte(),
                            ((Constant) result[6].operand1).asByte(), ((Constant) result[7].operand1).asByte()
                        }));
                        break;
                    case SHORT2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createShort2(new short2 {
                            ((Constant) result[0].operand1).asShort(), ((Constant) result[1].operand1).asShort()
                        }));
                        break;
                    case SHORT4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createShort4(new short4 {
                            ((Constant) result[0].operand1).asShort(), ((Constant) result[1].operand1).asShort(),
                            ((Constant) result[2].operand1).asShort(), ((Constant) result[3].operand1).asShort()
                        }));
                        break;
                    case SHORT8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createShort8(new short8 {
                            ((Constant) result[0].operand1).asShort(), ((Constant) result[1].operand1).asShort(),
                            ((Constant) result[2].operand1).asShort(), ((Constant) result[3].operand1).asShort(),
                            ((Constant) result[4].operand1).asShort(), ((Constant) result[5].operand1).asShort(),
                            ((Constant) result[6].operand1).asShort(), ((Constant) result[7].operand1).asShort()
                        }));
                        break;
                    case INT2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createInt2(new int2 {
                            ((Constant) result[0].operand1).asInt(), ((Constant) result[1].operand1).asInt()
                        }));
                        break;
                    case INT4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createInt4(new int4 {
                            ((Constant) result[0].operand1).asInt(), ((Constant) result[1].operand1).asInt(),
                            ((Constant) result[2].operand1).asInt(), ((Constant) result[3].operand1).asInt()
                        }));
                        break;
                    case INT8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createInt8(new int8 {
                            ((Constant) result[0].operand1).asInt(), ((Constant) result[1].operand1).asInt(),
                            ((Constant) result[2].operand1).asInt(), ((Constant) result[3].operand1).asInt(),
                            ((Constant) result[4].operand1).asInt(), ((Constant) result[5].operand1).asInt(),
                            ((Constant) result[6].operand1).asInt(), ((Constant) result[7].operand1).asInt()
                        }));
                        break;
                    case LONG2:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createLong2(new long2 {
                            ((Constant) result[0].operand1).asLong(), ((Constant) result[1].operand1).asLong()
                        }));
                        break;
                    case LONG4:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createLong4(new long4 {
                            ((Constant) result[0].operand1).asLong(), ((Constant) result[1].operand1).asLong(),
                            ((Constant) result[2].operand1).asLong(), ((Constant) result[3].operand1).asLong()
                        }));
                        break;
                    case LONG8:
                        result.setData(before, resultType, LOAD_CONST, fldConstantFactory.createLong8(new long8 {
                            ((Constant) result[0].operand1).asLong(), ((Constant) result[1].operand1).asLong(),
                            ((Constant) result[2].operand1).asLong(), ((Constant) result[3].operand1).asLong(),
                            ((Constant) result[4].operand1).asLong(), ((Constant) result[5].operand1).asLong(),
                            ((Constant) result[6].operand1).asLong(), ((Constant) result[7].operand1).asLong()
                        }));
                    }
                    code.removeChilds(result);
                }
                break;
            }
            if(resultType.isAbstract())
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.instantiate.abstract-type"), new Object[] { resultType }
                )) { source = source, position = before + 1 };
            }
            if(resultType instanceof ClassType)
            {
                if(source.getLexemeKind(position) != PARENTH_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
                }
                resultType.makeCompilable();
                Node result = code.createAndAppendNode(parent).setData(before, resultType, NEW_INSTANCE, resultType);
                Node constructor = code.createAndAppendNode(result);
                ClassType objectResultType = (ClassType) resultType;
                label1: if(source.getLexemeKind(++position) != PARENTH_CLOSED) do
                {
                    position = parseExpression(constructor, source, position, isStaticOnly);
                    requiresValue(constructor[-1]);
                    switch(source.getLexemeKind(position))
                    {
                    default:
                        throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                    case PARENTH_CLOSED:
                        break label1;
                    case COMMA:
                        position++;
                    }
                } while(true);
                int length = constructor.length;
                Type[] arguments = new Type[length];
                for(int index = 0; index < length; index++) arguments[index] = constructor[index].type;
                InstInit[] foundConstructors = objectResultType.findConstructors(arguments, enclosingClassType);
                int foundLength = foundConstructors == null ? 0 : foundConstructors.length;
                if(foundLength < 1)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("not-found.constructor"), new Object[] { objectResultType, ArgumentArray.toString(arguments) }
                    )) { source = source, position = before + 1 };
                }
                InstInit foundConstructor = foundConstructors[0];
                if(!foundConstructor.isConvertableArguments(arguments))
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("not-applicable.constructor"), new Object[] { foundConstructor, ArgumentArray.toString(arguments) }
                    )) { source = source, position = before + 1 };
                }
                if(!foundConstructor.isVisibleFrom(enclosingClassType, objectResultType))
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("invisible.constructor"), new Object[] { enclosingClassType.specialSimpleName, foundConstructor }
                    )) { source = source, position = before + 1 };
                }
                if(foundLength > 1)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("ambiguous.constructor"), new Object[] { objectResultType.specialCanonicalName + ArgumentArray.toString(arguments) }
                    )) { source = source, position = before + 1 };
                }
                for(ArgumentArray foundArguments = foundConstructor.arguments, int index = 0; index < length; index++) cast(constructor[index], foundArguments[index].type);
                code.createAndPrependNode(constructor).setData(-1, resultType, DUP1, resultType);
                constructor.setData(before + 1, foundConstructor.type, INVOKE_SPECIAL, foundConstructor);
                Callable foundMethod = fldTypeObject.getChildCallable("afterConstruction", (Type[]) null);
                if(foundMethod != null && !foundMethod.isStatic() && foundMethod.type.isVoid() && !foundMethod.canThrown())
                {
                    Node method = code.createAndAppendNode(result).setData(-1, fldTypeVoid, foundMethod.visibility <= PRIVATE ? INVOKE_SPECIAL : INVOKE_VIRTUAL, foundMethod);
                    code.createAndPrependNode(method).setData(-1, resultType, DUP1, resultType);
                }
                if(source.getLexemeKind(position + 1) == CURLY_OPENED && source.getLexemeKind(position += 2) != CURLY_CLOSED) do
                {
                    if(source.getLexemeKind(position) != L_NAME)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("expected.name.fieldoid"), new Object[] { objectResultType }
                        )) { source = source, position = position };
                    }
                    String name = source.getLexemeString(position);
                    TypedMember[] foundFieldoids = objectResultType.findFieldoids(name, enclosingClassType);
                    if((foundLength = foundFieldoids == null ? 0 : foundFieldoids.length) < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { objectResultType, name }
                        )) { source = source, position = position };
                    }
                    TypedMember foundFieldoid = foundFieldoids[0];
                    if(!foundFieldoid.isVisibleFrom(enclosingClassType, objectResultType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString(foundFieldoid instanceof Property ? "invisible.property" : "invisible.field"),
                            new Object[] { enclosingClassType.specialSimpleName, foundFieldoid }
                        )) { source = source, position = position };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.fieldoid"), new Object[] { new StringBuilder(0x0400) + objectResultType.specialCanonicalName + '.' + name }
                        )) { source = source, position = position };
                    }
                    Node write = code.createAndAppendNode(result);
                    if(foundFieldoid instanceof Field)
                    {
                        if(foundFieldoid.isStatic() || foundFieldoid.isFinal())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("must-be.instance-writeable-field"), new Object[] { foundFieldoid }
                            )) { source = source, position = position };
                        }
                        write.setData(position + 1, null, WRITE_FIELD, foundFieldoid);
                    }
                    else if(foundFieldoid instanceof Property)
                    {
                        if(foundFieldoid.isStatic() || !((Property) foundFieldoid).hasWrite())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("must-be.writeable-property"), new Object[] { foundFieldoid }
                            )) { source = source, position = position };
                        }
                        write.setData(position + 1, null, WRITE_PROPERTY, foundFieldoid);
                    }
                    else
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.fieldoid"), new Object[] { objectResultType, name }
                        )) { source = source, position = position };
                    }
                    if(source.getLexemeKind(++position) != EQUALS)
                    {
                        throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                    }
                    code.createAndPrependNode(write).setData(position - 1, resultType, DUP1, resultType);
                    position = parseExpression(write, source, position + 1, isStaticOnly);
                    Node value = write[-1];
                    requiresValue(value);
                    Type fieldType = foundFieldoid.type;
                    Type valueType = value.type;
                    if(!fieldType.isConvertableFrom(valueType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, fieldType }
                        )) { source = source, position = position };
                    }
                    cast(value, fieldType);
                    switch(source.getLexemeKind(position))
                    {
                    default:
                        throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
                    case CURLY_CLOSED:
                        break label0;
                    case COMMA:
                        position++;
                    }
                } while(true);
                break;
            }
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-be.instantiate.type"), new Object[] { resultType }
            )) { source = source, position = before + 1 };
        case VOID:
        case BOOLEAN:
        case CHAR:
        case REAL:
        case DOUBLE:
        case DOUBLE2:
        case DOUBLE4:
        case DOUBLE8:
        case FLOAT:
        case FLOAT2:
        case FLOAT4:
        case FLOAT8:
        case BYTE:
        case BYTE2:
        case BYTE4:
        case BYTE8:
        case SHORT:
        case SHORT2:
        case SHORT4:
        case SHORT8:
        case INT:
        case INT2:
        case INT4:
        case INT8:
        case LONG:
        case LONG2:
        case LONG4:
        case LONG8:
        case L_NAME:
            int before = position;
            TableItem foundItem;
            String name = source.getLexemeString(position);
            ImmediateBuilderItemHolder tableItemHolder = getItemHolder();
            tableItemHolder.helpersAllowed = true;
            try
            {
                if(operation != L_NAME)
                {
                    position = parseTypeName(source, before, enclosingClassType, tableItemHolder) - 1;
                    foundItem = tableItemHolder.resultItem;
                } else
                {
                    position = tryParseName(parent, source, before, name, tableItemHolder) - 1;
                    if((foundItem = tableItemHolder.resultItem) == null)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.some-variable"), new Object[] { name }
                        )) { source = source, position = before };
                    }
                    if(foundItem instanceof Type)
                    {
                        position = parseTypeName(source, before, enclosingClassType, tableItemHolder) - 1;
                        foundItem = tableItemHolder.resultItem;
                    }
                }
            } finally
            {
                tableItemHolder.helpersAllowed = false;
            }
            if(foundItem instanceof Local)
            {
                Local foundLocal = (Local) foundItem;
                if(foundLocal.isConstant())
                {
                    Constant foundValue = foundLocal.value;
                    code.createAndAppendNode(parent).setData(before, foundValue.type, LOAD_CONST, foundValue);
                    break;
                }
                code.createAndAppendNode(parent).setData(before, foundLocal.type, LOAD_LOCAL, foundLocal);
                break;
            }
            if(foundItem instanceof Member)
            {
                Local foundWith = tableItemHolder.resultWith;
                if(foundWith == null || isStaticOnly)
                {
                    code.createAndAppendNode(parent).setData(before, null, CLASS, enclosingClassType);
                }
                else if(!foundWith.isConstant())
                {
                    code.createAndAppendNode(parent).setData(before, foundWith.type, LOAD_LOCAL, foundWith);
                }
                else
                {
                    Constant foundValue = foundWith.value;
                    code.createAndAppendNode(parent).setData(before, foundValue.type, LOAD_CONST, foundValue);
                }
                isImplicitPeriod = true;
                position = before;
                break;
            }
            if(foundItem instanceof ClassType)
            {
                if(source.getLexemeKind(++position) != PERIOD)
                {
                    throw new TextSourceException(package.getResourceString("expected.period")) { source = source, position = position };
                }
                switch(source.getLexemeKind(++position))
                {
                case SUPER:
                    if(isStaticOnly)
                    {
                        throw new TextSourceException(package.getResourceString("can-not-reference.this")) { source = source, position = position };
                    }
                    if(enclosingCallable.isStatic())
                    {
                        throw new TextSourceException(package.getResourceString("can-not-use.static.this")) { source = source, position = position };
                    }
                    if(enclosingClassType.isHelper())
                    {
                        throw new TextSourceException(package.getResourceString("can-not-use.helper.super")) { source = source, position = position };
                    }
                    ClassType foundClassType = (ClassType) foundItem;
                    if(foundClassType.isHelper())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.some-variable"), new Object[] { name }
                        )) { source = source, position = before };
                    }
                    if(foundClassType.isClass() ? enclosingClassType.getSuperclassType() != foundClassType : !enclosingClassType.isSuperservice(foundClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("type.not-direct-supertype"), new Object[] { enclosingClassType.specialSimpleName, foundClassType }
                        )) { source = source, position = position };
                    }
                    code.createAndAppendNode(parent).setData(before, foundClassType, LOAD_LOCAL, enclosingCallable.arguments.thisArgument).useSuper = true;
                    break label0;
                case CLASS:
                    Type foundType = (Type) foundItem;
                    foundType.makeCompilable();
                    code.createAndAppendNode(parent).setData(before, fldTypeClass, LOAD_CONST, fldConstantFactory.createClass(foundType));
                    break label0;
                case L_NAME:
                    ClassType foundClassType = (ClassType) foundItem;
                    if(foundClassType.isHelper())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.some-variable"), new Object[] { name }
                        )) { source = source, position = before };
                    }
                    code.createAndAppendNode(parent).setData(before, null, CLASS, foundItem);
                    isImplicitPeriod = true;
                    break label0;
                default:
                    throw new TextSourceException(package.getResourceString("expected.name.static-member")) { source = source, position = position };
                }
            }
            if(foundItem instanceof PrimitiveType)
            {
                if(source.getLexemeKind(++position) != PERIOD)
                {
                    throw new TextSourceException(package.getResourceString("expected.period")) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != CLASS)
                {
                    throw new TextSourceException(package.getResourceString("expected.class")) { source = source, position = position };
                }
                Type foundType = (Type) foundItem;
                foundType.makeCompilable();
                code.createAndAppendNode(parent).setData(before, fldTypeClass, LOAD_CONST, fldConstantFactory.createClass(foundType));
                break;
            }
            if(foundItem instanceof Package)
            {
                if(source.getLexemeKind(++position) != PERIOD)
                {
                    throw new TextSourceException(package.getResourceString("expected.period")) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != PACKAGE)
                {
                    throw new TextSourceException(package.getResourceString("expected.package")) { source = source, position = position };
                }
                code.createAndAppendNode(parent).setData(before, fldTypePackage, LOAD_CONST, fldConstantFactory.createPackage((Package) foundItem));
                break;
            }
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-be.converted.some-variable"), new Object[] { name }
            )) { source = source, position = before };
        case OPERATOR:
            {
                ImmediateBuilderItemHolder operatorHolder = getItemHolder();
                parseOperator(source, position + 1, operatorHolder);
                int kind = operatorHolder.resultKind;
                tryParseName(parent, source, position, Operator.kindToSpecialSimpleName(kind), operatorHolder);
                TableItem foundItem = operatorHolder.resultItem;
                if(foundItem == null)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.converted.some-operator"), new Object[] { VIEWNAME_OPERATOR + Operator.kindToSymbol(kind) }
                    )) { source = source, position = position };
                }
                Local foundWith = operatorHolder.resultWith;
                if(foundWith == null || isStaticOnly)
                {
                    code.createAndAppendNode(parent).setData(position, null, CLASS, enclosingClassType);
                }
                else if(!foundWith.isConstant())
                {
                    code.createAndAppendNode(parent).setData(position, foundWith.type, LOAD_LOCAL, foundWith);
                }
                else
                {
                    Constant foundValue = foundWith.value;
                    code.createAndAppendNode(parent).setData(position, foundValue.type, LOAD_CONST, foundValue);
                }
                isImplicitPeriod = true;
                break;
            }
        case NULL:
            {
                code.createAndAppendNode(parent).setData(position, fldTypeNull, LOAD_CONST, fldNull);
                break;
            }
        case CLASS:
            {
                code.createAndAppendNode(parent).setData(position, fldTypeClass, LOAD_CONST, fldConstantFactory.createClass(enclosingClassType));
                break;
            }
        case PACKAGE:
            {
                code.createAndAppendNode(parent).setData(position, fldTypePackage, LOAD_CONST, fldConstantFactory.createPackage(enclosingClassType.parentPackage));
                break;
            }
        case L_STRING:
            {
                code.createAndAppendNode(parent).setData(position, fldTypeString, LOAD_CONST, fldConstantFactory.createString(source.getLexemeString(position)));
                break;
            }
        case L_BOOLEAN:
            {
                code.createAndAppendNode(parent).setData(position, fldTypeBoolean, LOAD_CONST, source.getLexemeBoolean(position) == false ? fldFalse : fldTrue);
                break;
            }
        case L_CHAR:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(CHAR), LOAD_CONST, fldConstantFactory.createChar(source.getLexemeChar(position)));
                break;
            }
        case L_REAL:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(REAL), LOAD_CONST, fldConstantFactory.createReal(source.getLexemeReal(position)));
                break;
            }
        case L_DOUBLE:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(DOUBLE), LOAD_CONST, fldConstantFactory.createDouble(source.getLexemeDouble(position)));
                break;
            }
        case L_FLOAT:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(FLOAT), LOAD_CONST, fldConstantFactory.createFloat(source.getLexemeFloat(position)));
                break;
            }
        case L_BYTE:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(BYTE), LOAD_CONST, fldConstantFactory.createByte((byte) source.getLexemeInt(position)));
                break;
            }
        case L_SHORT:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(SHORT), LOAD_CONST, fldConstantFactory.createShort((short) source.getLexemeInt(position)));
                break;
            }
        case L_INT:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(INT), LOAD_CONST, fldConstantFactory.createInt(source.getLexemeInt(position)));
                break;
            }
        case L_LONG:
            {
                code.createAndAppendNode(parent).setData(position, getPrimitiveType(LONG), LOAD_CONST, fldConstantFactory.createLong(source.getLexemeLong(position)));
                break;
            }
        default:
            throw new TextSourceException(package.getResourceString("error.expression")) { source = source, position = position };
        }
        return parsePostfix(parent, source, isImplicitPeriod ? position : position + 1, isStaticOnly, isImplicitPeriod);
    }

    private int parsePrefix(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        Code code = parent.parentCode;
        Callable enclosingCallable = code.parentCallable;
        ClassType enclosingClassType = enclosingCallable.parentType;
        Vector stack = null;
        label0: for(; ; position++)
        {
            int operation = source.getLexemeKind(position);
            switch(operation)
            {
            case INC_LOCAL:
            case DEC_LOCAL:
            case BOOL_NOT:
            case O_BIT_NOT:
            case O_VECT_LUP:
            case O_VECT_UUP:
            case O_VECT_PCK:
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(position, operation));
                break;
            case O_SCAL_ADD:
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(position, O_SCAL_POS));
                break;
            case O_SCAL_SUB:
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(position, O_SCAL_NEG));
                break;
            case O_VECT_ADD:
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(position, O_VECT_POS));
                break;
            case O_VECT_SUB:
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(position, O_VECT_NEG));
                break;
            case PARENTH_OPENED:
                int before = position++;
                ImmediateBuilderItemHolder newTypeHolder = getItemHolder();
                position = source.getLexemeKind(position) != L_NAME ? (
                    tryParseTypeName(source, position, enclosingClassType, newTypeHolder)
                ) : (
                    tryParseName(parent, source, position, source.getLexemeString(position), newTypeHolder)
                );
                Type newType = newTypeHolder.resultType;
                if(source.getLexemeKind(position) != PARENTH_CLOSED || newType == null || !newType.isVisibleFrom(enclosingClassType))
                {
                    position = before;
                    break label0;
                }
                if(stack == null) stack = new Vector();
                stack.append(new ImmediateBuilderUnaryOperation(before, CAST_TO, newType));
                break;
            default:
                break label0;
            }
        }
        position = parsePrimary(parent, source, position, isStaticOnly);
        if(stack != null) for(PrimitiveType typeInt = fldTypeInt, ConstantFactory factory = fldConstantFactory, Node child1 = parent[-1], int index = stack.length; index-- > 0; )
        {
            ImmediateBuilderUnaryOperation item = (ImmediateBuilderUnaryOperation) stack[index];
            Type argument1Type = child1.type;
            int operation = item.operation;
            int before = item.position;
            label0:
            {
                if(argument1Type instanceof NullType)
                {
                    if(operation == CAST_TO)
                    {
                        Type newType = item.newType;
                        if(newType instanceof ClassType)
                        {
                            Node result = code.createAndAppendNode(parent).setData(before, newType, NOP);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.type-cast"), new Object[] { argument1Type, newType }
                        )) { source = source, position = before };
                    }
                    break label0;
                }
                if(argument1Type instanceof ClassType)
                {
                    ClassType dereferenceClassType = (ClassType) argument1Type;
                    switch(operation)
                    {
                    case O_BIT_NOT:
                    case O_SCAL_POS:
                    case O_SCAL_NEG:
                    case O_VECT_LUP:
                    case O_VECT_UUP:
                    case O_VECT_PCK:
                    case O_VECT_POS:
                    case O_VECT_NEG:
                        {
                            Operator[] foundOperators = dereferenceClassType.findOperators(operation, null, enclosingClassType);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(null))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(null) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosingClassType, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                    case CAST_TO:
                        Type newType = item.newType;
                        if(newType instanceof ClassType)
                        {
                            if(newType == argument1Type || newType.isAssignableFrom(argument1Type))
                            {
                                Node result = code.createAndAppendNode(parent).setData(before, newType, NOP);
                                code.moveNode(child1, child1 = result, 0);
                                continue;
                            }
                            if(newType.isCompatibleWith(argument1Type))
                            {
                                newType.makeCompilable();
                                Node result = code.createAndAppendNode(parent).setData(before, newType, CAST_TO, newType, argument1Type);
                                code.moveNode(child1, child1 = result, 0);
                                continue;
                            }
                        }
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.type-cast"), new Object[] { argument1Type, newType }
                        )) { source = source, position = before };
                    }
                    break label0;
                }
                if(argument1Type instanceof PrimitiveType)
                {
                    int kind = argument1Type.kind;
                    int instruction = child1.instruction;
                    if(kind == CHAR)
                    {
                        kind = INT;
                        argument1Type = typeInt;
                    }
                    if(instruction == LOAD_CONST)
                    {
                        Constant result;
                        Constant operand1 = (Constant) child1.operand1;
                        label1: switch(operation)
                        {
                        case BOOL_NOT:
                            if(kind == BOOLEAN)
                            {
                                result = operand1.asBoolean() ? fldFalse : fldTrue;
                                break label1;
                            }
                            break label0;
                        case O_BIT_NOT:
                            switch(kind)
                            {
                            case BYTE:
                                result = factory.createByte(~operand1.asByte());
                                break label1;
                            case BYTE2:
                                result = factory.createByte2(~operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createByte4(~operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createByte8(~operand1.asByte8());
                                break label1;
                            case SHORT:
                                result = factory.createShort(~operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createShort2(~operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createShort4(~operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createShort8(~operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createInt(~operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createInt2(~operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createInt4(~operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createInt8(~operand1.asInt8());
                                break label1;
                            case LONG:
                                result = factory.createLong(~operand1.asLong());
                                break label1;
                            case LONG2:
                                result = factory.createLong2(~operand1.asLong2());
                                break label1;
                            case LONG4:
                                result = factory.createLong4(~operand1.asLong4());
                                break label1;
                            case LONG8:
                                result = factory.createLong8(~operand1.asLong8());
                                break label1;
                            }
                            break label0;
                        case O_SCAL_POS:
                            switch(kind)
                            {
                            case REAL:
                            case DOUBLE:
                            case DOUBLE2:
                            case DOUBLE4:
                            case DOUBLE8:
                            case FLOAT:
                            case FLOAT2:
                            case FLOAT4:
                            case FLOAT8:
                            case BYTE:
                            case SHORT:
                            case INT:
                            case INT2:
                            case INT4:
                            case INT8:
                            case LONG:
                            case LONG2:
                            case LONG4:
                            case LONG8:
                                result = operand1;
                                break label1;
                            case BYTE2:
                                result = factory.createInt2(operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createInt4(operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createInt8(operand1.asByte8());
                                break label1;
                            case SHORT2:
                                result = factory.createInt2(operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createInt4(operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createInt8(operand1.asShort8());
                                break label1;
                            }
                            break label0;
                        case O_SCAL_NEG:
                            switch(kind)
                            {
                            case REAL:
                                result = factory.createReal(-operand1.asReal());
                                break label1;
                            case DOUBLE:
                                result = factory.createDouble(-operand1.asDouble());
                                break label1;
                            case DOUBLE2:
                                result = factory.createDouble2(-operand1.asDouble2());
                                break label1;
                            case DOUBLE4:
                                result = factory.createDouble4(-operand1.asDouble4());
                                break label1;
                            case DOUBLE8:
                                result = factory.createDouble8(-operand1.asDouble8());
                                break label1;
                            case FLOAT:
                                result = factory.createFloat(-operand1.asFloat());
                                break label1;
                            case FLOAT2:
                                result = factory.createFloat2(-operand1.asFloat2());
                                break label1;
                            case FLOAT4:
                                result = factory.createFloat4(-operand1.asFloat4());
                                break label1;
                            case FLOAT8:
                                result = factory.createFloat8(-operand1.asFloat8());
                                break label1;
                            case BYTE:
                                result = factory.createIntegral(-operand1.asByte());
                                break label1;
                            case BYTE2:
                                result = factory.createInt2(-operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createInt4(-operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createInt8(-operand1.asByte8());
                                break label1;
                            case SHORT:
                                result = factory.createIntegral(-operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createInt2(-operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createInt4(-operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createInt8(-operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createIntegral(-operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createInt2(-operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createInt4(-operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createInt8(-operand1.asInt8());
                                break label1;
                            case LONG:
                                result = factory.createLong(-operand1.asLong());
                                break label1;
                            case LONG2:
                                result = factory.createLong2(-operand1.asLong2());
                                break label1;
                            case LONG4:
                                result = factory.createLong4(-operand1.asLong4());
                                break label1;
                            case LONG8:
                                result = factory.createLong8(-operand1.asLong8());
                                break label1;
                            }
                            break label0;
                        case O_VECT_POS:
                            switch(kind)
                            {
                            case DOUBLE:
                            case DOUBLE2:
                            case DOUBLE4:
                            case DOUBLE8:
                            case FLOAT:
                            case FLOAT2:
                            case FLOAT4:
                            case FLOAT8:
                            case BYTE:
                            case BYTE2:
                            case BYTE4:
                            case BYTE8:
                            case SHORT:
                            case SHORT2:
                            case SHORT4:
                            case SHORT8:
                            case INT:
                            case INT2:
                            case INT4:
                            case INT8:
                            case LONG:
                            case LONG2:
                            case LONG4:
                            case LONG8:
                                result = operand1;
                                break label1;
                            }
                            break label0;
                        case O_VECT_NEG:
                            switch(kind)
                            {
                            case DOUBLE:
                                result = factory.createDouble(----operand1.asDouble());
                                break label1;
                            case DOUBLE2:
                                result = factory.createDouble2(----operand1.asDouble2());
                                break label1;
                            case DOUBLE4:
                                result = factory.createDouble4(----operand1.asDouble4());
                                break label1;
                            case DOUBLE8:
                                result = factory.createDouble8(----operand1.asDouble8());
                                break label1;
                            case FLOAT:
                                result = factory.createFloat(----operand1.asFloat());
                                break label1;
                            case FLOAT2:
                                result = factory.createFloat2(----operand1.asFloat2());
                                break label1;
                            case FLOAT4:
                                result = factory.createFloat4(----operand1.asFloat4());
                                break label1;
                            case FLOAT8:
                                result = factory.createFloat8(----operand1.asFloat8());
                                break label1;
                            case BYTE:
                                result = factory.createByte(----operand1.asByte());
                                break label1;
                            case BYTE2:
                                result = factory.createByte2(----operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createByte4(----operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createByte8(----operand1.asByte8());
                                break label1;
                            case SHORT:
                                result = factory.createShort(----operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createShort2(----operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createShort4(----operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createShort8(----operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createInt(----operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createInt2(----operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createInt4(----operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createInt8(----operand1.asInt8());
                                break label1;
                            case LONG:
                                result = factory.createLong(----operand1.asLong());
                                break label1;
                            case LONG2:
                                result = factory.createLong2(----operand1.asLong2());
                                break label1;
                            case LONG4:
                                result = factory.createLong4(----operand1.asLong4());
                                break label1;
                            case LONG8:
                                result = factory.createLong8(----operand1.asLong8());
                                break label1;
                            }
                            break label0;
                        case O_VECT_PCK:
                            if(kind >= BYTE && kind <= BYTE8)
                            {
                                operand1 = operand1.castTo(getPrimitiveType(kind += SHORT - BYTE));
                            }
                            switch(kind)
                            {
                            case SHORT:
                                result = factory.createByte(@@@@operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createByte2(@@@@operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createByte4(@@@@operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createByte8(@@@@operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createShort(@@@@operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createShort2(@@@@operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createShort4(@@@@operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createShort8(@@@@operand1.asInt8());
                                break label1;
                            case LONG:
                                result = factory.createInt(@@@@operand1.asLong());
                                break label1;
                            case LONG2:
                                result = factory.createInt2(@@@@operand1.asLong2());
                                break label1;
                            case LONG4:
                                result = factory.createInt4(@@@@operand1.asLong4());
                                break label1;
                            case LONG8:
                                result = factory.createInt8(@@@@operand1.asLong8());
                                break label1;
                            }
                            break label0;
                        case O_VECT_LUP:
                            switch(kind)
                            {
                            case BYTE:
                                result = factory.createShort(####operand1.asByte());
                                break label1;
                            case BYTE2:
                                result = factory.createShort2(####operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createShort4(####operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createShort8(####operand1.asByte8());
                                break label1;
                            case SHORT:
                                result = factory.createInt(####operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createInt2(####operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createInt4(####operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createInt8(####operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createLong(####operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createLong2(####operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createLong4(####operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createLong8(####operand1.asInt8());
                                break label1;
                            }
                            break label0;
                        case O_VECT_UUP:
                            switch(kind)
                            {
                            case BYTE:
                                result = factory.createShort(^^^^operand1.asByte());
                                break label1;
                            case BYTE2:
                                result = factory.createShort2(^^^^operand1.asByte2());
                                break label1;
                            case BYTE4:
                                result = factory.createShort4(^^^^operand1.asByte4());
                                break label1;
                            case BYTE8:
                                result = factory.createShort8(^^^^operand1.asByte8());
                                break label1;
                            case SHORT:
                                result = factory.createInt(^^^^operand1.asShort());
                                break label1;
                            case SHORT2:
                                result = factory.createInt2(^^^^operand1.asShort2());
                                break label1;
                            case SHORT4:
                                result = factory.createInt4(^^^^operand1.asShort4());
                                break label1;
                            case SHORT8:
                                result = factory.createInt8(^^^^operand1.asShort8());
                                break label1;
                            case INT:
                                result = factory.createLong(^^^^operand1.asInt());
                                break label1;
                            case INT2:
                                result = factory.createLong2(^^^^operand1.asInt2());
                                break label1;
                            case INT4:
                                result = factory.createLong4(^^^^operand1.asInt4());
                                break label1;
                            case INT8:
                                result = factory.createLong8(^^^^operand1.asInt8());
                                break label1;
                            }
                            break label0;
                        case CAST_TO:
                            Type newType = item.newType;
                            if(newType.isBoolean() && argument1Type.isBoolean())
                            {
                                result = operand1;
                                break label1;
                            }
                            if(newType.isNumeric() && argument1Type.isNumeric())
                            {
                                result = operand1.castTo(newType);
                                break label1;
                            }
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.type-cast"), new Object[] { argument1Type, newType }
                            )) { source = source, position = before };
                        case INC_LOCAL:
                        case DEC_LOCAL:
                            throw new TextSourceException(String.format(
                                package.getResourceString("applicable.operator.increment-decrement"), new Object[] { source.getLexemeString(before) }
                            )) { source = source, position = before };
                        }
                        child1.setData(before, result.type, LOAD_CONST, result);
                        continue;
                    }
                    Type resultType;
                    switch(operation)
                    {
                    case BOOL_NOT:
                        if(kind == BOOLEAN)
                        {
                            resultType = argument1Type;
                            break;
                        }
                        break label0;
                    case O_BIT_NOT:
                        if(kind >= BYTE && kind <= LONG8)
                        {
                            resultType = argument1Type;
                            break;
                        }
                        break label0;
                    case O_SCAL_POS:
                        if(kind >= BYTE && kind <= SHORT8)
                        {
                            resultType = getPrimitiveType(INT + (kind & 3));
                            Node result = kind != BYTE && kind != SHORT ? (
                                code.createAndAppendNode(parent).setData(before, resultType, CAST_TO, resultType, argument1Type)
                            ) : (
                                code.createAndAppendNode(parent).setData(before, resultType, NOP)
                            );
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        if(argument1Type.isNumeric())
                        {
                            Node result = code.createAndAppendNode(parent).setData(before, argument1Type, NOP);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        break label0;
                    case O_SCAL_NEG:
                        if(kind >= BYTE && kind <= SHORT8)
                        {
                            resultType = getPrimitiveType(INT + (kind & 3));
                            if(kind != BYTE && kind != SHORT)
                            {
                                Node result = code.createAndAppendNode(parent).setData(before, resultType, CAST_TO, resultType, argument1Type);
                                code.moveNode(child1, child1 = result, 0);
                            }
                            argument1Type = resultType;
                            break;
                        }
                        if(argument1Type.isNumeric())
                        {
                            resultType = argument1Type;
                            break;
                        }
                        break label0;
                    case O_VECT_POS:
                        if(kind >= DOUBLE && kind <= LONG8)
                        {
                            Node result = code.createAndAppendNode(parent).setData(before, argument1Type, NOP);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        break label0;
                    case O_VECT_NEG:
                        if(kind >= DOUBLE && kind <= LONG8)
                        {
                            resultType = argument1Type;
                            break;
                        }
                        break label0;
                    case O_VECT_PCK:
                        if(kind >= BYTE && kind <= BYTE8)
                        {
                            resultType = getPrimitiveType(kind += SHORT - BYTE);
                            Node result = code.createAndAppendNode(parent).setData(before, resultType, CAST_TO, resultType, argument1Type);
                            code.moveNode(child1, child1 = result, 0);
                            argument1Type = resultType;
                        }
                        if(kind >= SHORT && kind <= LONG8)
                        {
                            resultType = getPrimitiveType(kind + (BYTE - SHORT));
                            break;
                        }
                        break label0;
                    case O_VECT_LUP:
                    case O_VECT_UUP:
                        if(kind >= BYTE && kind <= INT8)
                        {
                            resultType = getPrimitiveType(kind + (SHORT - BYTE));
                            break;
                        }
                        break label0;
                    case CAST_TO:
                        Type newType = item.newType;
                        if(newType.isBoolean() && argument1Type.isBoolean())
                        {
                            Node result = code.createAndAppendNode(parent).setData(before, newType, NOP);
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        if(newType.isNumeric() && argument1Type.isNumeric())
                        {
                            Node result = newType != argument1Type ? (
                                code.createAndAppendNode(parent).setData(before, newType, CAST_TO, newType, argument1Type)
                            ) : (
                                code.createAndAppendNode(parent).setData(before, newType, NOP)
                            );
                            code.moveNode(child1, child1 = result, 0);
                            continue;
                        }
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.type-cast"), new Object[] { argument1Type, newType }
                        )) { source = source, position = before };
                    case INC_LOCAL:
                    case DEC_LOCAL:
                        switch(instruction)
                        {
                        case LOAD_LOCAL:
                            {
                                Local foundLocal = (Local) child1.operand1;
                                if(foundLocal.isFinal())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.access.local-final.write"), new Object[] { foundLocal }
                                    )) { source = source, position = before };
                                }
                                if(!((argument1Type = foundLocal.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                                    )) { source = source, position = before };
                                }
                                child1.setData(child1.position, argument1Type, operation == INC_LOCAL ? INC_PRED_LOAD_LOCAL : DEC_PRED_LOAD_LOCAL, foundLocal);
                                continue;
                            }
                        case LOAD_STATIC:
                            {
                                Field foundField = (Field) child1.operand1;
                                if(foundField.isFinal() && (!(enclosingCallable instanceof ClassInit) || foundField.parentType != enclosingClassType || foundField.value != null))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundField }
                                    )) { source = source, position = before };
                                }
                                if(!((argument1Type = foundField.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                                    )) { source = source, position = before };
                                }
                                Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                                code.createAndPrependNode(delta).setData(child1.position, argument1Type, LOAD_STATIC, foundField);
                                code.createAndAppendNode(child1).setData(-1, null, DUP1, argument1Type);
                                child1.setData(-1, argument1Type, STORE_STATIC, foundField);
                                continue;
                            }
                        case READ_FIELD:
                        case READ_SPECIAL:
                        case READ_PROPERTY:
                            {
                                TypedMember foundFieldoid = (TypedMember) child1.operand1;
                                if(foundFieldoid instanceof Property)
                                {
                                    if(!((Property) foundFieldoid).hasWrite())
                                    {
                                        throw new TextSourceException(String.format(
                                            package.getResourceString("can-not-be.access.property-read-only.write"), new Object[] { foundFieldoid }
                                        )) { source = source, position = before };
                                    }
                                } else
                                {
                                    Node load = child1[0];
                                    if(
                                        foundFieldoid.isFinal() && (
                                            !(enclosingCallable instanceof InstInit) || foundFieldoid.parentType != enclosingClassType ||
                                            load.instruction != LOAD_LOCAL || load.operand1 != enclosingCallable.arguments.thisArgument
                                        )
                                    )
                                    {
                                        throw new TextSourceException(String.format(
                                            package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundFieldoid }
                                        )) { source = source, position = before };
                                    }
                                }
                                if(!((argument1Type = foundFieldoid.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                                    )) { source = source, position = before };
                                }
                                Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                                Node read = code.createAndPrependNode(delta).setData(child1.position, argument1Type, instruction, foundFieldoid);
                                code.createAndAppendNode(read).setData(-1, null, DUP1, fldTypeObject);
                                code.createAndAppendNode(child1).setData(-1, null, DUP1X1, argument1Type);
                                child1.setData(-1, argument1Type, instruction + A_DELTA, foundFieldoid);
                                continue;
                            }
                        case READ_COMPONENT:
                            {
                                if(!((argument1Type = (Type) child1.operand1) instanceof PrimitiveType) || !argument1Type.isNumeric())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                                    )) { source = source, position = before };
                                }
                                Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                                Node read = code.createAndPrependNode(delta).setData(child1.position, argument1Type, READ_COMPONENT, argument1Type);
                                code.createAndAppendNode(read).setData(-1, null, DUP2, fldTypeInt);
                                code.createAndAppendNode(child1).setData(-1, null, DUP1X2, argument1Type);
                                child1.setData(-1, argument1Type, WRITE_COMPONENT, argument1Type);
                                continue;
                            }
                        case INVOKE_SERVICE:
                        case INVOKE_SPECIAL:
                        case INVOKE_VIRTUAL:
                            Operator foundReadOperator;
                            TableItem foundCallable = child1.operand1;
                            if(foundCallable instanceof Operator && (foundReadOperator = (Operator) foundCallable).kind == READ_COMPONENT)
                            {
                                if(!((argument1Type = foundReadOperator.type) instanceof PrimitiveType) || !argument1Type.isNumeric())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                                    )) { source = source, position = before };
                                }
                                Node load = child1[0];
                                ClassType dereferenceClassType = (ClassType) load.type;
                                Type[] arguments = new Type[] { foundReadOperator.arguments[0].type, argument1Type };
                                Operator[] foundOperators = dereferenceClassType.findOperators(WRITE_COMPONENT, arguments, enclosingClassType);
                                Operator foundWriteOperator = foundOperators == null || foundOperators.length != 1 ? null : foundOperators[0];
                                if(foundWriteOperator == null || !foundWriteOperator.isIdentityArguments(arguments))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-found.operator"),
                                        new Object[] { dereferenceClassType, Operator.kindToSymbol(WRITE_COMPONENT) + ArgumentArray.toString(arguments) }
                                    )) { source = source, position = before };
                                }
                                boolean isUseSuper = load.useSuper;
                                if(!foundWriteOperator.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundWriteOperator }
                                    )) { source = source, position = before };
                                }
                                if(isUseSuper && foundWriteOperator.isAbstract())
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundWriteOperator }
                                    )) { source = source, position = before };
                                }
                                Node delta = appendIncrementCode(child1, (PrimitiveType) argument1Type, operation == INC_LOCAL);
                                Node read = code.createAndPrependNode(delta).setData(child1.position, argument1Type, instruction, foundReadOperator);
                                code.createAndAppendNode(read).setData(-1, null, DUP2, arguments[0]);
                                code.createAndAppendNode(child1).setData(-1, null, DUP1X2, argument1Type);
                                child1.setData(-1, argument1Type, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundWriteOperator, dereferenceClassType), foundWriteOperator);
                                continue;
                            }
                        }
                        throw new TextSourceException(String.format(
                            package.getResourceString("applicable.operator.increment-decrement"), new Object[] { source.getLexemeString(before) }
                        )) { source = source, position = before };
                    }
                    Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, operation == BOOL_NOT ? null : argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    continue;
                }
            }
            throw new TextSourceException(String.format(
                package.getResourceString("not-defined.operator.1"),
                new Object[] { operation != CAST_TO ? source.getLexemeString(before) : package.getResourceString("operator.type-cast"), argument1Type }
            )) { source = source, position = before };
        }
        return position;
    }

    private int parseMultiplicative(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parsePrefix(parent, source, position, isStaticOnly));
        if(
            operation == O_SCAL_MUL || operation == O_SCAL_DIV || operation == O_SCAL_DIVU || operation == O_SCAL_REM || operation == O_SCAL_REMU ||
            operation == O_VECT_MUL || operation == O_VECT_DIV || operation == O_VECT_HMUL || operation == O_VECT_HMULU
        )
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parsePrefix(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(operation, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = operation >= O_VECT_OPERATOR ? argument1Type.getVectorCommonType(argument2Type) : argument1Type.getScalarCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            label1: switch(operation)
                            {
                            case O_SCAL_MUL:
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() * operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() * operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() * operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() * operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() * operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() * operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() * operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() * operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() * operand2.asFloat8());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() * operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() * operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() * operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() * operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() * operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() * operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() * operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() * operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_DIV:
                                if((kind == INT || kind == LONG) && operand2.isDefaultValue())
                                {
                                    throw new TextSourceException(package.getResourceString("error.int-div-by-zero")) { source = source, position = before };
                                }
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() / operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() / operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() / operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() / operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() / operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() / operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() / operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() / operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() / operand2.asFloat8());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() / operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() / operand2.asLong());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_DIVU:
                                if((kind == INT || kind == LONG) && operand2.isDefaultValue())
                                {
                                    throw new TextSourceException(package.getResourceString("error.int-div-by-zero")) { source = source, position = before };
                                }
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() // operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() // operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() // operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() // operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() // operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() // operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() // operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() // operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() // operand2.asFloat8());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() // operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() // operand2.asLong());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_REM:
                                if((kind == INT || kind == LONG) && operand2.isDefaultValue())
                                {
                                    throw new TextSourceException(package.getResourceString("error.int-div-by-zero")) { source = source, position = before };
                                }
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() % operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() % operand2.asDouble());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() % operand2.asFloat());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() % operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() % operand2.asLong());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_REMU:
                                if((kind == INT || kind == LONG) && operand2.isDefaultValue())
                                {
                                    throw new TextSourceException(package.getResourceString("error.int-div-by-zero")) { source = source, position = before };
                                }
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() %% operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() %% operand2.asDouble());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() %% operand2.asFloat());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() %% operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() %% operand2.asLong());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_MUL:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() **** operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() **** operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() **** operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() **** operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() **** operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() **** operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() **** operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() **** operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() **** operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() **** operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() **** operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() **** operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() **** operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() **** operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() **** operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() **** operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() **** operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() **** operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() **** operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() **** operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() **** operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() **** operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() **** operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() **** operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_DIV:
                                if(kind >= BYTE && kind <= LONG8)
                                {
                                    kind = DOUBLE | kind & 3;
                                }
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() //// operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() //// operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() //// operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() //// operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() //// operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() //// operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() //// operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() //// operand2.asFloat8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_HMUL:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |**| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |**| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |**| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |**| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |**| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |**| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |**| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |**| operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_HMULU:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() #**# operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() #**# operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() #**# operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() #**# operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() #**# operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() #**# operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() #**# operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() #**# operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        Type resultType;
                        switch(operation)
                        {
                        case O_SCAL_MUL:
                            if(kind >= REAL && kind <= FLOAT8 || kind >= INT && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_SCAL_DIV:
                        case O_SCAL_DIVU:
                            if(kind >= REAL && kind <= FLOAT8 || kind == INT || kind == LONG)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_SCAL_REM:
                        case O_SCAL_REMU:
                            if(kind == REAL || kind == DOUBLE || kind == FLOAT || kind == INT || kind == LONG)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_MUL:
                            if(kind >= DOUBLE && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_DIV:
                            if(kind >= BYTE && kind <= LONG8)
                            {
                                commonType = getPrimitiveType(kind = DOUBLE | kind & 3);
                            }
                            if(kind >= DOUBLE && kind <= FLOAT8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_HMUL:
                        case O_VECT_HMULU:
                            if(kind >= BYTE && kind <= SHORT8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        }
                        child1 = cast(child1, commonType);
                        child2 = cast(child2, commonType);
                        Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, commonType);
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(operation += R_DELTA, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(
                (operation = source.getLexemeKind(position)) == O_SCAL_MUL || operation == O_SCAL_DIV || operation == O_SCAL_DIVU || operation == O_SCAL_REM || operation == O_SCAL_REMU ||
                operation == O_VECT_MUL || operation == O_VECT_DIV || operation == O_VECT_HMUL || operation == O_VECT_HMULU
            );
        }
        return position;
    }

    private int parseAdditive(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parseMultiplicative(parent, source, position, isStaticOnly));
        if(
            operation == O_SCAL_ADD || operation == O_SCAL_SUB || operation == O_VECT_SADD || operation == O_VECT_SADDU ||
            operation == O_VECT_ADD || operation == O_VECT_SUB || operation == O_VECT_SSUB || operation == O_VECT_SSUBU
        )
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseMultiplicative(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    ClassType typeString = fldTypeString;
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            if(operation == O_SCAL_ADD && argument1Type == typeString && child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                            {
                                if(argument2Type == typeString)
                                {
                                    String operand1 = (String) ((Constant) child1.operand1).asObject();
                                    String operand2 = (String) ((Constant) child2.operand1).asObject();
                                    if(operand1 != null && operand2 != null)
                                    {
                                        child1.setData(child1.position, typeString, LOAD_CONST, factory.createString(operand1 + operand2));
                                        code.removeNode(child2);
                                        continue;
                                    }
                                }
                                else if(argument2Type == getPrimitiveType(CHAR))
                                {
                                    String operand1 = (String) ((Constant) child1.operand1).asObject();
                                    if(operand1 != null)
                                    {
                                        char operand2 = ((Constant) child2.operand1).asChar();
                                        child1.setData(child1.position, typeString, LOAD_CONST, factory.createString(operand1 + operand2));
                                        code.removeNode(child2);
                                        continue;
                                    }
                                }
                            }
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(operation, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = operation >= O_VECT_OPERATOR ? argument1Type.getVectorCommonType(argument2Type) : argument1Type.getScalarCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            label1: switch(operation)
                            {
                            case O_SCAL_ADD:
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() + operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() + operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() + operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() + operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() + operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() + operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() + operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() + operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() + operand2.asFloat8());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() + operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() + operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() + operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() + operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() + operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() + operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() + operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() + operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_SUB:
                                switch(kind)
                                {
                                case REAL:
                                    result = factory.createReal(operand1.asReal() - operand2.asReal());
                                    break label1;
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() - operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() - operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() - operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() - operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() - operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() - operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() - operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() - operand2.asFloat8());
                                    break label1;
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() - operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() - operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() - operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() - operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() - operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() - operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() - operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() - operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_ADD:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() ++++ operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() ++++ operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() ++++ operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() ++++ operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() ++++ operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() ++++ operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() ++++ operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() ++++ operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() ++++ operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() ++++ operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() ++++ operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() ++++ operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() ++++ operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() ++++ operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() ++++ operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() ++++ operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() ++++ operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() ++++ operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() ++++ operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() ++++ operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() ++++ operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() ++++ operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() ++++ operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() ++++ operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SUB:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createDouble(operand1.asDouble() ---- operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createDouble2(operand1.asDouble2() ---- operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createDouble4(operand1.asDouble4() ---- operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createDouble8(operand1.asDouble8() ---- operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createFloat(operand1.asFloat() ---- operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createFloat2(operand1.asFloat2() ---- operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createFloat4(operand1.asFloat4() ---- operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createFloat8(operand1.asFloat8() ---- operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() ---- operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() ---- operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() ---- operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() ---- operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() ---- operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() ---- operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() ---- operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() ---- operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() ---- operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() ---- operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() ---- operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() ---- operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() ---- operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() ---- operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() ---- operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() ---- operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SADD:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |++| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |++| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |++| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |++| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |++| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |++| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |++| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |++| operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SADDU:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() #++# operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() #++# operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() #++# operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() #++# operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() #++# operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() #++# operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() #++# operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() #++# operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SSUB:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |--| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |--| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |--| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |--| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |--| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |--| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |--| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |--| operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SSUBU:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() #--# operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() #--# operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() #--# operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() #--# operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() #--# operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() #--# operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() #--# operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() #--# operand2.asShort8());
                                    break label1;
                                }
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        Type resultType;
                        switch(operation)
                        {
                        case O_SCAL_ADD:
                        case O_SCAL_SUB:
                            if(kind >= REAL && kind <= FLOAT8 || kind >= INT && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_ADD:
                        case O_VECT_SUB:
                            if(kind >= DOUBLE && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_SADD:
                        case O_VECT_SADDU:
                        case O_VECT_SSUB:
                        case O_VECT_SSUBU:
                            if(kind >= BYTE && kind <= SHORT8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        }
                        child1 = cast(child1, commonType);
                        child2 = cast(child2, commonType);
                        Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, commonType);
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    if(operation == O_SCAL_ADD && argument1Type == getPrimitiveType(CHAR) && argument2Type == typeString && child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                    {
                        String operand2 = (String) ((Constant) child2.operand1).asObject();
                        if(operand2 != null)
                        {
                            char operand1 = ((Constant) child1.operand1).asChar();
                            child1.setData(child1.position, typeString, LOAD_CONST, factory.createString((new StringBuilder() + operand1 + operand2).toString()));
                            code.removeNode(child2);
                            continue;
                        }
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(operation += R_DELTA, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(
                (operation = source.getLexemeKind(position)) == O_SCAL_ADD || operation == O_SCAL_SUB || operation == O_VECT_SADD || operation == O_VECT_SADDU ||
                operation == O_VECT_ADD || operation == O_VECT_SUB || operation == O_VECT_SSUB || operation == O_VECT_SSUBU
            );
        }
        return position;
    }

    private int parseShift(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parseAdditive(parent, source, position, isStaticOnly));
        if(
            operation == O_SCAL_SHR || operation == O_SCAL_SHRU || operation == O_SCAL_SHL ||
            operation == O_VECT_SHR || operation == O_VECT_SHRU || operation == O_VECT_SHL
        )
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseAdditive(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(operation, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType) || !argument2Type.isInt()) break label0;
                        Type commonType = operation >= O_VECT_OPERATOR ? argument1Type : argument1Type.getScalarCommonType(argument1Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            label1: switch(operation)
                            {
                            case O_SCAL_SHR:
                                switch(kind)
                                {
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() >> operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() >> operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() >> operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() >> operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() >> operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() >> operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() >> operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() >> operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_SHRU:
                                switch(kind)
                                {
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() >>> operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() >>> operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() >>> operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() >>> operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() >>> operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() >>> operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() >>> operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() >>> operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_SHL:
                                switch(kind)
                                {
                                case INT:
                                    result = factory.createIntegral(operand1.asInt() << operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() << operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() << operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() << operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() << operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() << operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() << operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() << operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SHR:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() >>>> operand2.asInt());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() >>>> operand2.asInt());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() >>>> operand2.asInt());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() >>>> operand2.asInt());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() >>>> operand2.asInt());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() >>>> operand2.asInt());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() >>>> operand2.asInt());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() >>>> operand2.asInt());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() >>>> operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() >>>> operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() >>>> operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() >>>> operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() >>>> operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() >>>> operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() >>>> operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() >>>> operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SHRU:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() >>>>> operand2.asInt());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() >>>>> operand2.asInt());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() >>>>> operand2.asInt());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() >>>>> operand2.asInt());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() >>>>> operand2.asInt());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() >>>>> operand2.asInt());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() >>>>> operand2.asInt());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() >>>>> operand2.asInt());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() >>>>> operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() >>>>> operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() >>>>> operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() >>>>> operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() >>>>> operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() >>>>> operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() >>>>> operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() >>>>> operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_SHL:
                                switch(kind)
                                {
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() <<<< operand2.asInt());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() <<<< operand2.asInt());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() <<<< operand2.asInt());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() <<<< operand2.asInt());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() <<<< operand2.asInt());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() <<<< operand2.asInt());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() <<<< operand2.asInt());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() <<<< operand2.asInt());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() <<<< operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() <<<< operand2.asInt());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() <<<< operand2.asInt());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() <<<< operand2.asInt());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() <<<< operand2.asInt());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() <<<< operand2.asInt());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() <<<< operand2.asInt());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() <<<< operand2.asInt());
                                    break label1;
                                }
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        Type resultType;
                        switch(operation)
                        {
                        case O_SCAL_SHR:
                        case O_SCAL_SHRU:
                        case O_SCAL_SHL:
                            if(kind >= INT && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        case O_VECT_SHR:
                        case O_VECT_SHRU:
                        case O_VECT_SHL:
                            if(kind >= BYTE && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        }
                        child1 = cast(child1, commonType);
                        Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, commonType);
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(operation += R_DELTA, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(
                (operation = source.getLexemeKind(position)) == O_SCAL_SHR || operation == O_SCAL_SHRU || operation == O_SCAL_SHL ||
                operation == O_VECT_SHR || operation == O_VECT_SHRU || operation == O_VECT_SHL
            );
        }
        return position;
    }

    private int parseRelational(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parseShift(parent, source, position, isStaticOnly));
        if(
            operation == O_SCAL_GT || operation == O_SCAL_GE || operation == O_SCAL_LT || operation == O_SCAL_LE ||
            operation == O_VECT_GT || operation == O_VECT_GE || operation == O_VECT_LT || operation == O_VECT_LE ||
            operation == INSTANCEOF
        )
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                if(operation == INSTANCEOF)
                {
                    Type argument1Type = child1.type;
                    if(!(argument1Type instanceof ClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-defined.operator.1"), new Object[] { source.getLexemeString(before), argument1Type }
                        )) { source = source, position = before };
                    }
                    ImmediateBuilderItemHolder checkTypeHolder = getItemHolder();
                    position = parseTypeName(source, position + 1, enclosing, checkTypeHolder);
                    Type checkType = checkTypeHolder.resultType;
                    if(!(checkType instanceof ClassType))
                    {
                        throw new TextSourceException(package.getResourceString("expected.name.class-type")) { source = source, position = before + 1 };
                    }
                    if(!argument1Type.isCompatibleWith(checkType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("incompatible-types"), new Object[] { argument1Type, checkType }
                        )) { source = source, position = before };
                    }
                    checkType.makeCompilable();
                    Node result = code.createAndAppendNode(parent).setData(before, fldTypeBoolean, INSTANCEOF, checkType);
                    code.moveNode(child1, child1 = result, 0);
                    continue;
                }
                position = parseShift(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(operation, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = operation >= O_VECT_OPERATOR ? argument1Type.getVectorCommonType(argument2Type) : argument1Type.getScalarCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            label1: switch(operation)
                            {
                            case O_SCAL_GT:
                                switch(kind)
                                {
                                case REAL:
                                    result = operand1.asReal() > operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() > operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() > operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() > operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() > operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_GE:
                                switch(kind)
                                {
                                case REAL:
                                    result = operand1.asReal() >= operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() >= operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() >= operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() >= operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() >= operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_LT:
                                switch(kind)
                                {
                                case REAL:
                                    result = operand1.asReal() < operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() < operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() < operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() < operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() < operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_LE:
                                switch(kind)
                                {
                                case REAL:
                                    result = operand1.asReal() <= operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() <= operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() <= operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() <= operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() <= operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_VECT_GT:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |>>| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |>>| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |>>| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |>>| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |>>| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |>>| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |>>| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |>>| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |>>| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |>>| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |>>| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |>>| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |>>| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |>>| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |>>| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |>>| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |>>| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |>>| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |>>| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |>>| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |>>| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |>>| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |>>| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |>>| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_GE:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |>=| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |>=| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |>=| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |>=| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |>=| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |>=| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |>=| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |>=| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |>=| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |>=| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |>=| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |>=| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |>=| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |>=| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |>=| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |>=| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |>=| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |>=| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |>=| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |>=| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |>=| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |>=| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |>=| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |>=| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_LT:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |<<| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |<<| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |<<| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |<<| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |<<| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |<<| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |<<| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |<<| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |<<| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |<<| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |<<| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |<<| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |<<| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |<<| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |<<| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |<<| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |<<| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |<<| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |<<| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |<<| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |<<| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |<<| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |<<| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |<<| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_LE:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |<=| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |<=| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |<=| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |<=| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |<=| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |<=| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |<=| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |<=| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |<=| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |<=| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |<=| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |<=| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |<=| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |<=| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |<=| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |<=| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |<=| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |<=| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |<=| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |<=| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |<=| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |<=| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |<=| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |<=| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        Type resultType;
                        switch(operation)
                        {
                        case O_SCAL_GT:
                        case O_SCAL_GE:
                        case O_SCAL_LT:
                        case O_SCAL_LE:
                            if(kind == REAL || kind == DOUBLE || kind == FLOAT || kind == INT || kind == LONG)
                            {
                                resultType = fldTypeBoolean;
                                break;
                            }
                            break label0;
                        case O_VECT_GT:
                        case O_VECT_GE:
                        case O_VECT_LT:
                        case O_VECT_LE:
                            if(kind >= DOUBLE && kind <= DOUBLE8)
                            {
                                resultType = getPrimitiveType(kind + (LONG - DOUBLE));
                                break;
                            }
                            if(kind >= FLOAT && kind <= FLOAT8)
                            {
                                resultType = getPrimitiveType(kind + (INT - FLOAT));
                                break;
                            }
                            if(kind >= BYTE && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        }
                        child1 = cast(child1, commonType);
                        child2 = cast(child2, commonType);
                        Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, commonType);
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(operation += R_DELTA, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(
                (operation = source.getLexemeKind(position)) == O_SCAL_GT || operation == O_SCAL_GE || operation == O_SCAL_LT || operation == O_SCAL_LE ||
                operation == O_VECT_GT || operation == O_VECT_GE || operation == O_VECT_LT || operation == O_VECT_LE ||
                operation == INSTANCEOF
            );
        }
        return position;
    }

    private int parseEquality(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parseRelational(parent, source, position, isStaticOnly));
        if(operation == O_SCAL_EQ || operation == O_SCAL_NE || operation == O_VECT_EQ || operation == O_VECT_NE)
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseRelational(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    if((operation == O_SCAL_EQ || operation == O_SCAL_NE) && argument1Type instanceof ReferenceType)
                    {
                        if(!argument1Type.isCompatibleWith(argument2Type))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("incompatible-types"), new Object[] { argument1Type, argument2Type }
                            )) { source = source, position = before };
                        }
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Object operand1 = ((Constant) child1.operand1).asObject();
                            Object operand2 = ((Constant) child2.operand1).asObject();
                            child1.setData(child1.position, fldTypeBoolean, LOAD_CONST, (operation == O_SCAL_EQ ? operand1 == operand2 : operand1 != operand2) ? fldTrue : fldFalse);
                            code.removeNode(child2);
                            continue;
                        }
                        Node result = code.createAndAppendNode(parent).setData(before, fldTypeBoolean, operation + (REF_EQ - O_SCAL_EQ));
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    label1:
                    {
                        if(operation == O_VECT_EQ || operation == O_VECT_NE)
                        {
                            if(argument1Type instanceof ClassType)
                            {
                                ClassType dereferenceClassType = (ClassType) argument1Type;
                                Type[] arguments = new Type[] { argument2Type };
                                Operator[] foundOperators = dereferenceClassType.findOperators(operation, arguments, enclosing);
                                int foundLength = foundOperators == null ? 0 : foundOperators.length;
                                if(foundLength < 1)
                                {
                                    if(argument2Type instanceof ClassType) break label1;
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                                    )) { source = source, position = before };
                                }
                                Operator foundOperator = foundOperators[0];
                                if(!foundOperator.isConvertableArguments(arguments))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                    )) { source = source, position = before };
                                }
                                if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                    )) { source = source, position = before };
                                }
                                if(foundLength > 1)
                                {
                                    throw new TextSourceException(String.format(
                                        package.getResourceString("ambiguous.operator"),
                                        new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                                    )) { source = source, position = before };
                                }
                                child2 = cast(child2, foundOperator.arguments[0].type);
                                Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                                code.moveNode(child1, child1 = result, 0);
                                code.moveNode(child2, result, 1);
                                continue;
                            }
                            if(argument2Type instanceof ClassType) break label1;
                        }
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = operation >= O_VECT_OPERATOR ? argument1Type.getVectorCommonType(argument2Type) : argument1Type.getScalarCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            label1: switch(operation)
                            {
                            case O_SCAL_EQ:
                                switch(kind)
                                {
                                case BOOLEAN:
                                    result = operand1.asBoolean() == operand2.asBoolean() ? fldTrue : fldFalse;
                                    break label1;
                                case REAL:
                                    result = operand1.asReal() == operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() == operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE2:
                                    result = operand1.asDouble2() == operand2.asDouble2() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE4:
                                    result = operand1.asDouble4() == operand2.asDouble4() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE8:
                                    result = operand1.asDouble8() == operand2.asDouble8() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() == operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT2:
                                    result = operand1.asFloat2() == operand2.asFloat2() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT4:
                                    result = operand1.asFloat4() == operand2.asFloat4() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT8:
                                    result = operand1.asFloat8() == operand2.asFloat8() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() == operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case INT2:
                                    result = operand1.asInt2() == operand2.asInt2() ? fldTrue : fldFalse;
                                    break label1;
                                case INT4:
                                    result = operand1.asInt4() == operand2.asInt4() ? fldTrue : fldFalse;
                                    break label1;
                                case INT8:
                                    result = operand1.asInt8() == operand2.asInt8() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() == operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG2:
                                    result = operand1.asLong2() == operand2.asLong2() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG4:
                                    result = operand1.asLong4() == operand2.asLong4() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG8:
                                    result = operand1.asLong8() == operand2.asLong8() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_SCAL_NE:
                                switch(kind)
                                {
                                case BOOLEAN:
                                    result = operand1.asBoolean() != operand2.asBoolean() ? fldTrue : fldFalse;
                                    break label1;
                                case REAL:
                                    result = operand1.asReal() != operand2.asReal() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE:
                                    result = operand1.asDouble() != operand2.asDouble() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE2:
                                    result = operand1.asDouble2() != operand2.asDouble2() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE4:
                                    result = operand1.asDouble4() != operand2.asDouble4() ? fldTrue : fldFalse;
                                    break label1;
                                case DOUBLE8:
                                    result = operand1.asDouble8() != operand2.asDouble8() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT:
                                    result = operand1.asFloat() != operand2.asFloat() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT2:
                                    result = operand1.asFloat2() != operand2.asFloat2() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT4:
                                    result = operand1.asFloat4() != operand2.asFloat4() ? fldTrue : fldFalse;
                                    break label1;
                                case FLOAT8:
                                    result = operand1.asFloat8() != operand2.asFloat8() ? fldTrue : fldFalse;
                                    break label1;
                                case INT:
                                    result = operand1.asInt() != operand2.asInt() ? fldTrue : fldFalse;
                                    break label1;
                                case INT2:
                                    result = operand1.asInt2() != operand2.asInt2() ? fldTrue : fldFalse;
                                    break label1;
                                case INT4:
                                    result = operand1.asInt4() != operand2.asInt4() ? fldTrue : fldFalse;
                                    break label1;
                                case INT8:
                                    result = operand1.asInt8() != operand2.asInt8() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG:
                                    result = operand1.asLong() != operand2.asLong() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG2:
                                    result = operand1.asLong2() != operand2.asLong2() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG4:
                                    result = operand1.asLong4() != operand2.asLong4() ? fldTrue : fldFalse;
                                    break label1;
                                case LONG8:
                                    result = operand1.asLong8() != operand2.asLong8() ? fldTrue : fldFalse;
                                    break label1;
                                }
                                break label0;
                            case O_VECT_EQ:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |==| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |==| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |==| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |==| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |==| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |==| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |==| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |==| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |==| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |==| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |==| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |==| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |==| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |==| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |==| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |==| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |==| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |==| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |==| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |==| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |==| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |==| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |==| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |==| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            case O_VECT_NE:
                                switch(kind)
                                {
                                case DOUBLE:
                                    result = factory.createLong(operand1.asDouble() |!=| operand2.asDouble());
                                    break label1;
                                case DOUBLE2:
                                    result = factory.createLong2(operand1.asDouble2() |!=| operand2.asDouble2());
                                    break label1;
                                case DOUBLE4:
                                    result = factory.createLong4(operand1.asDouble4() |!=| operand2.asDouble4());
                                    break label1;
                                case DOUBLE8:
                                    result = factory.createLong8(operand1.asDouble8() |!=| operand2.asDouble8());
                                    break label1;
                                case FLOAT:
                                    result = factory.createInt(operand1.asFloat() |!=| operand2.asFloat());
                                    break label1;
                                case FLOAT2:
                                    result = factory.createInt2(operand1.asFloat2() |!=| operand2.asFloat2());
                                    break label1;
                                case FLOAT4:
                                    result = factory.createInt4(operand1.asFloat4() |!=| operand2.asFloat4());
                                    break label1;
                                case FLOAT8:
                                    result = factory.createInt8(operand1.asFloat8() |!=| operand2.asFloat8());
                                    break label1;
                                case BYTE:
                                    result = factory.createByte(operand1.asByte() |!=| operand2.asByte());
                                    break label1;
                                case BYTE2:
                                    result = factory.createByte2(operand1.asByte2() |!=| operand2.asByte2());
                                    break label1;
                                case BYTE4:
                                    result = factory.createByte4(operand1.asByte4() |!=| operand2.asByte4());
                                    break label1;
                                case BYTE8:
                                    result = factory.createByte8(operand1.asByte8() |!=| operand2.asByte8());
                                    break label1;
                                case SHORT:
                                    result = factory.createShort(operand1.asShort() |!=| operand2.asShort());
                                    break label1;
                                case SHORT2:
                                    result = factory.createShort2(operand1.asShort2() |!=| operand2.asShort2());
                                    break label1;
                                case SHORT4:
                                    result = factory.createShort4(operand1.asShort4() |!=| operand2.asShort4());
                                    break label1;
                                case SHORT8:
                                    result = factory.createShort8(operand1.asShort8() |!=| operand2.asShort8());
                                    break label1;
                                case INT:
                                    result = factory.createInt(operand1.asInt() |!=| operand2.asInt());
                                    break label1;
                                case INT2:
                                    result = factory.createInt2(operand1.asInt2() |!=| operand2.asInt2());
                                    break label1;
                                case INT4:
                                    result = factory.createInt4(operand1.asInt4() |!=| operand2.asInt4());
                                    break label1;
                                case INT8:
                                    result = factory.createInt8(operand1.asInt8() |!=| operand2.asInt8());
                                    break label1;
                                case LONG:
                                    result = factory.createLong(operand1.asLong() |!=| operand2.asLong());
                                    break label1;
                                case LONG2:
                                    result = factory.createLong2(operand1.asLong2() |!=| operand2.asLong2());
                                    break label1;
                                case LONG4:
                                    result = factory.createLong4(operand1.asLong4() |!=| operand2.asLong4());
                                    break label1;
                                case LONG8:
                                    result = factory.createLong8(operand1.asLong8() |!=| operand2.asLong8());
                                    break label1;
                                }
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        Type resultType;
                        switch(operation)
                        {
                        case O_SCAL_EQ:
                        case O_SCAL_NE:
                            if(kind == BOOLEAN || kind >= REAL && kind <= FLOAT8 || kind >= INT && kind <= LONG8)
                            {
                                resultType = fldTypeBoolean;
                                break;
                            }
                            break label0;
                        case O_VECT_EQ:
                        case O_VECT_NE:
                            if(kind >= DOUBLE && kind <= DOUBLE8)
                            {
                                resultType = getPrimitiveType(kind + (LONG - DOUBLE));
                                break;
                            }
                            if(kind >= FLOAT && kind <= FLOAT8)
                            {
                                resultType = getPrimitiveType(kind + (INT - FLOAT));
                                break;
                            }
                            if(kind >= BYTE && kind <= LONG8)
                            {
                                resultType = commonType;
                                break;
                            }
                            break label0;
                        }
                        child1 = cast(child1, commonType);
                        child2 = cast(child2, commonType);
                        Node result = code.createAndAppendNode(parent).setData(before, resultType, operation, commonType);
                        code.moveNode(child1, child1 = result, 0);
                        code.moveNode(child2, result, 1);
                        continue;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(operation += R_DELTA, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(operation) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(operation) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while((operation = source.getLexemeKind(position)) == O_SCAL_EQ || operation == O_SCAL_NE || operation == O_VECT_EQ || operation == O_VECT_NE);
        }
        return position;
    }

    private int parseBitAnd(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseEquality(parent, source, position, isStaticOnly)) == O_BIT_AND)
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseEquality(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(O_BIT_AND, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(O_BIT_AND) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(O_BIT_AND) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = argument1Type.getVectorCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            switch(kind)
                            {
                            case BOOLEAN:
                                result = operand1.asBoolean() & operand2.asBoolean() ? fldTrue : fldFalse;
                                break;
                            case BYTE:
                                result = factory.createByte(operand1.asByte() & operand2.asByte());
                                break;
                            case BYTE2:
                                result = factory.createByte2(operand1.asByte2() & operand2.asByte2());
                                break;
                            case BYTE4:
                                result = factory.createByte4(operand1.asByte4() & operand2.asByte4());
                                break;
                            case BYTE8:
                                result = factory.createByte8(operand1.asByte8() & operand2.asByte8());
                                break;
                            case SHORT:
                                result = factory.createShort(operand1.asShort() & operand2.asShort());
                                break;
                            case SHORT2:
                                result = factory.createShort2(operand1.asShort2() & operand2.asShort2());
                                break;
                            case SHORT4:
                                result = factory.createShort4(operand1.asShort4() & operand2.asShort4());
                                break;
                            case SHORT8:
                                result = factory.createShort8(operand1.asShort8() & operand2.asShort8());
                                break;
                            case INT:
                                result = factory.createInt(operand1.asInt() & operand2.asInt());
                                break;
                            case INT2:
                                result = factory.createInt2(operand1.asInt2() & operand2.asInt2());
                                break;
                            case INT4:
                                result = factory.createInt4(operand1.asInt4() & operand2.asInt4());
                                break;
                            case INT8:
                                result = factory.createInt8(operand1.asInt8() & operand2.asInt8());
                                break;
                            case LONG:
                                result = factory.createLong(operand1.asLong() & operand2.asLong());
                                break;
                            case LONG2:
                                result = factory.createLong2(operand1.asLong2() & operand2.asLong2());
                                break;
                            case LONG4:
                                result = factory.createLong4(operand1.asLong4() & operand2.asLong4());
                                break;
                            case LONG8:
                                result = factory.createLong8(operand1.asLong8() & operand2.asLong8());
                                break;
                            default:
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        if(kind == BOOLEAN || kind >= BYTE && kind <= LONG8)
                        {
                            Type resultType = commonType;
                            child1 = cast(child1, commonType);
                            child2 = cast(child2, commonType);
                            Node result = code.createAndAppendNode(parent).setData(before, resultType, O_BIT_AND, commonType);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        break label0;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(R_BIT_AND, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(R_BIT_AND) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(R_BIT_AND) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(source.getLexemeKind(position) == O_BIT_AND);
        }
        return position;
    }

    private int parseBitXor(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseBitAnd(parent, source, position, isStaticOnly)) == O_BIT_XOR)
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseBitAnd(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(O_BIT_XOR, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(O_BIT_XOR) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(O_BIT_XOR) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = argument1Type.getVectorCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            switch(kind)
                            {
                            case BOOLEAN:
                                result = operand1.asBoolean() ^ operand2.asBoolean() ? fldTrue : fldFalse;
                                break;
                            case BYTE:
                                result = factory.createByte(operand1.asByte() ^ operand2.asByte());
                                break;
                            case BYTE2:
                                result = factory.createByte2(operand1.asByte2() ^ operand2.asByte2());
                                break;
                            case BYTE4:
                                result = factory.createByte4(operand1.asByte4() ^ operand2.asByte4());
                                break;
                            case BYTE8:
                                result = factory.createByte8(operand1.asByte8() ^ operand2.asByte8());
                                break;
                            case SHORT:
                                result = factory.createShort(operand1.asShort() ^ operand2.asShort());
                                break;
                            case SHORT2:
                                result = factory.createShort2(operand1.asShort2() ^ operand2.asShort2());
                                break;
                            case SHORT4:
                                result = factory.createShort4(operand1.asShort4() ^ operand2.asShort4());
                                break;
                            case SHORT8:
                                result = factory.createShort8(operand1.asShort8() ^ operand2.asShort8());
                                break;
                            case INT:
                                result = factory.createInt(operand1.asInt() ^ operand2.asInt());
                                break;
                            case INT2:
                                result = factory.createInt2(operand1.asInt2() ^ operand2.asInt2());
                                break;
                            case INT4:
                                result = factory.createInt4(operand1.asInt4() ^ operand2.asInt4());
                                break;
                            case INT8:
                                result = factory.createInt8(operand1.asInt8() ^ operand2.asInt8());
                                break;
                            case LONG:
                                result = factory.createLong(operand1.asLong() ^ operand2.asLong());
                                break;
                            case LONG2:
                                result = factory.createLong2(operand1.asLong2() ^ operand2.asLong2());
                                break;
                            case LONG4:
                                result = factory.createLong4(operand1.asLong4() ^ operand2.asLong4());
                                break;
                            case LONG8:
                                result = factory.createLong8(operand1.asLong8() ^ operand2.asLong8());
                                break;
                            default:
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        if(kind == BOOLEAN || kind >= BYTE && kind <= LONG8)
                        {
                            Type resultType = commonType;
                            child1 = cast(child1, commonType);
                            child2 = cast(child2, commonType);
                            Node result = code.createAndAppendNode(parent).setData(before, resultType, O_BIT_XOR, commonType);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        break label0;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(R_BIT_XOR, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(R_BIT_XOR) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(R_BIT_XOR) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(source.getLexemeKind(position) == O_BIT_XOR);
        }
        return position;
    }

    private int parseBitOr(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseBitXor(parent, source, position, isStaticOnly)) == O_BIT_OR)
        {
            Code code = parent.parentCode;
            ClassType enclosing = code.parentCallable.parentType;
            ConstantFactory factory = fldConstantFactory;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseBitXor(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    label1:
                    {
                        if(argument1Type instanceof ClassType)
                        {
                            ClassType dereferenceClassType = (ClassType) argument1Type;
                            Type[] arguments = new Type[] { argument2Type };
                            Operator[] foundOperators = dereferenceClassType.findOperators(O_BIT_OR, arguments, enclosing);
                            int foundLength = foundOperators == null ? 0 : foundOperators.length;
                            if(foundLength < 1)
                            {
                                if(argument2Type instanceof ClassType) break label1;
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(O_BIT_OR) }
                                )) { source = source, position = before };
                            }
                            Operator foundOperator = foundOperators[0];
                            if(!foundOperator.isConvertableArguments(arguments))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                                )) { source = source, position = before };
                            }
                            if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                                )) { source = source, position = before };
                            }
                            if(foundLength > 1)
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("ambiguous.operator"),
                                    new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(O_BIT_OR) + foundOperator.arguments }
                                )) { source = source, position = before };
                            }
                            child2 = cast(child2, foundOperator.arguments[0].type);
                            Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        if(argument2Type instanceof ClassType) break label1;
                        if(!(argument1Type instanceof PrimitiveType)) break label0;
                        Type commonType = argument1Type.getVectorCommonType(argument2Type);
                        if(commonType == null) break label0;
                        int kind = commonType.kind;
                        if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                        {
                            Constant result;
                            Constant operand1 = (Constant) child1.operand1;
                            Constant operand2 = (Constant) child2.operand1;
                            switch(kind)
                            {
                            case BOOLEAN:
                                result = operand1.asBoolean() | operand2.asBoolean() ? fldTrue : fldFalse;
                                break;
                            case BYTE:
                                result = factory.createByte(operand1.asByte() | operand2.asByte());
                                break;
                            case BYTE2:
                                result = factory.createByte2(operand1.asByte2() | operand2.asByte2());
                                break;
                            case BYTE4:
                                result = factory.createByte4(operand1.asByte4() | operand2.asByte4());
                                break;
                            case BYTE8:
                                result = factory.createByte8(operand1.asByte8() | operand2.asByte8());
                                break;
                            case SHORT:
                                result = factory.createShort(operand1.asShort() | operand2.asShort());
                                break;
                            case SHORT2:
                                result = factory.createShort2(operand1.asShort2() | operand2.asShort2());
                                break;
                            case SHORT4:
                                result = factory.createShort4(operand1.asShort4() | operand2.asShort4());
                                break;
                            case SHORT8:
                                result = factory.createShort8(operand1.asShort8() | operand2.asShort8());
                                break;
                            case INT:
                                result = factory.createInt(operand1.asInt() | operand2.asInt());
                                break;
                            case INT2:
                                result = factory.createInt2(operand1.asInt2() | operand2.asInt2());
                                break;
                            case INT4:
                                result = factory.createInt4(operand1.asInt4() | operand2.asInt4());
                                break;
                            case INT8:
                                result = factory.createInt8(operand1.asInt8() | operand2.asInt8());
                                break;
                            case LONG:
                                result = factory.createLong(operand1.asLong() | operand2.asLong());
                                break;
                            case LONG2:
                                result = factory.createLong2(operand1.asLong2() | operand2.asLong2());
                                break;
                            case LONG4:
                                result = factory.createLong4(operand1.asLong4() | operand2.asLong4());
                                break;
                            case LONG8:
                                result = factory.createLong8(operand1.asLong8() | operand2.asLong8());
                                break;
                            default:
                                break label0;
                            }
                            child1.setData(child1.position, result.type, LOAD_CONST, result);
                            code.removeNode(child2);
                            continue;
                        }
                        if(kind == BOOLEAN || kind >= BYTE && kind <= LONG8)
                        {
                            Type resultType = commonType;
                            child1 = cast(child1, commonType);
                            child2 = cast(child2, commonType);
                            Node result = code.createAndAppendNode(parent).setData(before, resultType, O_BIT_OR, commonType);
                            code.moveNode(child1, child1 = result, 0);
                            code.moveNode(child2, result, 1);
                            continue;
                        }
                        break label0;
                    }
                    ClassType dereferenceClassType = (ClassType) argument2Type;
                    Type[] arguments = new Type[] { argument1Type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(R_BIT_OR, arguments, enclosing);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(R_BIT_OR) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    if(!foundOperator.isVisibleFrom(enclosing, dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosing.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(R_BIT_OR) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    child1 = cast(child1, foundOperator.arguments[0].type);
                    Node result = code.createAndAppendNode(parent).setData(before, foundOperator.type, invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    code.createAndAppendNode(result).setData(before, null, SWAP, argument1Type);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(source.getLexemeKind(position) == O_BIT_OR);
        }
        return position;
    }

    private int parseBoolAnd(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseBitOr(parent, source, position, isStaticOnly)) == BOOL_AND)
        {
            Code code = parent.parentCode;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseBitOr(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                if(argument1Type.isBoolean() && argument2Type.isBoolean())
                {
                    if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                    {
                        Constant result = ((Constant) child1.operand1).asBoolean() & ((Constant) child2.operand1).asBoolean() ? fldTrue : fldFalse;
                        child1.setData(child1.position, result.type, LOAD_CONST, result);
                        code.removeNode(child2);
                        continue;
                    }
                    Node result = code.createAndAppendNode(parent).setData(before, argument1Type, BOOL_AND);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(source.getLexemeKind(position) == BOOL_AND);
        }
        return position;
    }

    private int parseBoolOr(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseBoolAnd(parent, source, position, isStaticOnly)) == BOOL_OR)
        {
            Code code = parent.parentCode;
            Node child1 = parent[-1];
            do
            {
                int before = position;
                position = parseBoolAnd(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                if(argument1Type.isBoolean() && argument2Type.isBoolean())
                {
                    if(child1.instruction == LOAD_CONST && child2.instruction == LOAD_CONST)
                    {
                        Constant result = ((Constant) child1.operand1).asBoolean() | ((Constant) child2.operand1).asBoolean() ? fldTrue : fldFalse;
                        child1.setData(child1.position, result.type, LOAD_CONST, result);
                        code.removeNode(child2);
                        continue;
                    }
                    Node result = code.createAndAppendNode(parent).setData(before, argument1Type, BOOL_OR);
                    code.moveNode(child1, child1 = result, 0);
                    code.moveNode(child2, result, 1);
                    continue;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), argument1Type, argument2Type }
                )) { source = source, position = before };
            } while(source.getLexemeKind(position) == BOOL_OR);
        }
        return position;
    }

    private int parseConditional(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        if(source.getLexemeKind(position = parseBoolOr(parent, source, position, isStaticOnly)) == QUESTION)
        {
            int question = position;
            Node child1 = parent[-1];
            Type argument1Type = child1.type;
            if(!argument1Type.isBoolean())
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("expected.expression.type"), new Object[] { fldTypeBoolean, argument1Type }
                )) { source = source, position = question };
            }
            if(child1.instruction == LOAD_CONST)
            {
                throw new TextSourceException(package.getResourceString("can-not-be.const-expression-before-question")) { source = source, position = question };
            }
            int colon = position = parseExpression(parent, source, position + 1, isStaticOnly);
            if(source.getLexemeKind(position) != COLON)
            {
                throw new TextSourceException(package.getResourceString("expected.colon")) { source = source, position = position };
            }
            position = parseExpression(parent, source, position + 1, isStaticOnly);
            Node child2 = parent[-2];
            Node child3 = parent[-1];
            requiresValue(child2);
            requiresValue(child3);
            Type argument2Type = child2.type;
            Type argument3Type = child3.type;
            Type commonType = argument2Type.getVectorCommonType(argument3Type);
            if(commonType == null)
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-define.common-type"), new Object[] { argument2Type, argument3Type }
                )) { source = source, position = colon };
            }
            child2 = cast(child2, commonType);
            child3 = cast(child3, commonType);
            Code code = parent.parentCode;
            Node result = code.createAndAppendNode(parent).setData(question, commonType, BOOL_COND);
            code.moveNode(child1, result, 0);
            code.moveNode(child2, result, 1);
            code.moveNode(child3, result, 2);
        }
        return position;
    }

    private int parseExpression(Node parent, TextSource source, int position, boolean isStaticOnly) throws TextSourceException {
        int operation = source.getLexemeKind(position = parseConditional(parent, source, position, isStaticOnly));
        label0: switch(operation)
        {
        case EQUALS:
            Node left = parent[-1];
            int before = position;
            int instruction = left.instruction;
            switch(instruction)
            {
            case LOAD_LOCAL:
                {
                    Local foundLocal = (Local) left.operand1;
                    if(foundLocal.isFinal())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.access.local-final.write"), new Object[] { foundLocal }
                        )) { source = source, position = before };
                    }
                    Type leftType = foundLocal.type;
                    position = parseExpression(left, source, position + 1, isStaticOnly);
                    Node right = left[-1];
                    requiresValue(right);
                    Type rightType = right.type;
                    if(!leftType.isConvertableFrom(rightType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { rightType, leftType }
                        )) { source = source, position = before };
                    }
                    cast(right, leftType);
                    left.setData(before, null, STORE_LOCAL, foundLocal);
                    break label0;
                }
            case LOAD_STATIC:
                {
                    Field foundField = (Field) left.operand1;
                    Callable enclosingCallable = parent.parentCode.parentCallable;
                    ClassType enclosingClassType = enclosingCallable.parentType;
                    if(foundField.isFinal() && (!(enclosingCallable instanceof ClassInit) || foundField.parentType != enclosingClassType || foundField.value != null))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundField }
                        )) { source = source, position = before };
                    }
                    Type leftType = foundField.type;
                    position = parseExpression(left, source, position + 1, isStaticOnly);
                    Node right = left[-1];
                    requiresValue(right);
                    Type rightType = right.type;
                    if(!leftType.isConvertableFrom(rightType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { rightType, leftType }
                        )) { source = source, position = before };
                    }
                    cast(right, leftType);
                    left.setData(before, null, STORE_STATIC, foundField);
                    break label0;
                }
            case WRITE_SPECIAL:
            case WRITE_PROPERTY:
                if(left.length != 1) break;
                /* падение через */
            case READ_FIELD:
            case READ_SPECIAL:
            case READ_PROPERTY:
                {
                    TypedMember foundFieldoid = (TypedMember) left.operand1;
                    if(foundFieldoid instanceof Property)
                    {
                        if(!((Property) foundFieldoid).hasWrite())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.property-read-only.write"), new Object[] { foundFieldoid }
                            )) { source = source, position = before };
                        }
                    } else
                    {
                        Node load = left[0];
                        Callable enclosingCallable = parent.parentCode.parentCallable;
                        ClassType enclosingClassType = enclosingCallable.parentType;
                        if(
                            foundFieldoid.isFinal() && (
                                !(enclosingCallable instanceof InstInit) || foundFieldoid.parentType != enclosingClassType ||
                                load.instruction != LOAD_LOCAL || load.operand1 != enclosingCallable.arguments.thisArgument
                            )
                        )
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundFieldoid }
                            )) { source = source, position = before };
                        }
                    }
                    Type leftType = foundFieldoid.type;
                    position = parseExpression(left, source, position + 1, isStaticOnly);
                    Node right = left[-1];
                    requiresValue(right);
                    Type rightType = right.type;
                    if(!leftType.isConvertableFrom(rightType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { rightType, leftType }
                        )) { source = source, position = before };
                    }
                    cast(right, leftType);
                    left.setData(before, null, instruction >= WRITE_OPERATOR ? instruction : instruction + A_DELTA, foundFieldoid);
                    break label0;
                }
            case READ_COMPONENT:
                {
                    Type leftType = (Type) left.type;
                    position = parseExpression(left, source, position + 1, isStaticOnly);
                    Node right = left[-1];
                    requiresValue(right);
                    Type rightType = right.type;
                    if(!leftType.isConvertableFrom(rightType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.type"), new Object[] { rightType, leftType }
                        )) { source = source, position = before };
                    }
                    cast(right, leftType);
                    left.setData(before, null, WRITE_COMPONENT, leftType);
                    break label0;
                }
            case INVOKE_VIRTUAL:
                if(left.operand1 == null)
                {
                    position = parseExpression(left, source, position + 1, isStaticOnly);
                    Node load = left[0];
                    Node index = left[1];
                    Node value = left[2];
                    requiresValue(value);
                    ClassType enclosingClassType = parent.parentCode.parentCallable.parentType;
                    ClassType dereferenceClassType = (ClassType) load.type;
                    Type[] arguments = new Type[] { index.type, value.type };
                    Operator[] foundOperators = dereferenceClassType.findOperators(WRITE_COMPONENT, arguments, enclosingClassType);
                    int foundLength = foundOperators == null ? 0 : foundOperators.length;
                    if(foundLength < 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.converted.operator"), new Object[] { dereferenceClassType, VIEWNAME_OPERATOR + Operator.kindToSymbol(WRITE_COMPONENT) }
                        )) { source = source, position = before };
                    }
                    Operator foundOperator = foundOperators[0];
                    if(!foundOperator.isConvertableArguments(arguments))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("not-applicable.operator"), new Object[] { foundOperator, ArgumentArray.toString(arguments) }
                        )) { source = source, position = before };
                    }
                    boolean isUseSuper = load.useSuper;
                    if(!foundOperator.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundOperator }
                        )) { source = source, position = before };
                    }
                    if(foundLength > 1)
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("ambiguous.operator"),
                            new Object[] { new StringBuilder(0x0400) + dereferenceClassType + ("." + VIEWNAME_OPERATOR) + Operator.kindToSymbol(WRITE_COMPONENT) + foundOperator.arguments }
                        )) { source = source, position = before };
                    }
                    if(isUseSuper && foundOperator.isAbstract())
                    {
                        throw new TextSourceException(String.format(
                            package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundOperator }
                        )) { source = source, position = before };
                    }
                    with(foundOperator.arguments)
                    {
                        cast(index, operator [](0).type);
                        cast(value, operator [](1).type);
                    }
                    left.setData(before, null, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundOperator, dereferenceClassType), foundOperator);
                    break label0;
                }
            }
            throw new TextSourceException(String.format(
                package.getResourceString("applicable.operator.increment-decrement"), new Object[] { source.getLexemeString(before) }
            )) { source = source, position = before };
        case A_BIT_AND:
        case A_BIT_OR:
        case A_BIT_XOR:
        case A_SCAL_MUL:
        case A_SCAL_DIV:
        case A_SCAL_DIVU:
        case A_SCAL_REM:
        case A_SCAL_REMU:
        case A_SCAL_ADD:
        case A_SCAL_SUB:
        case A_SCAL_SHR:
        case A_SCAL_SHRU:
        case A_SCAL_SHL:
        case A_VECT_MUL:
        case A_VECT_DIV:
        case A_VECT_ADD:
        case A_VECT_SUB:
        case A_VECT_SHR:
        case A_VECT_SHRU:
        case A_VECT_SHL:
        case A_VECT_GT:
        case A_VECT_GE:
        case A_VECT_LT:
        case A_VECT_LE:
        case A_VECT_EQ:
        case A_VECT_NE:
        case A_VECT_HMUL:
        case A_VECT_HMULU:
        case A_VECT_SADD:
        case A_VECT_SADDU:
        case A_VECT_SSUB:
        case A_VECT_SSUBU:
            Type leftType;
            Node action;
            Node right;
            Node left = parent[-1];
            Code code = parent.parentCode;
            int before = position;
            operation -= A_DELTA;
            label1:
            {
                int instruction = left.instruction;
                switch(instruction)
                {
                case LOAD_LOCAL:
                    {
                        Local foundLocal = (Local) left.operand1;
                        if(foundLocal.isFinal())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.local-final.write"), new Object[] { foundLocal }
                            )) { source = source, position = before };
                        }
                        leftType = foundLocal.type;
                        position = parseExpression(action = code.createAndAppendNode(left), source, position + 1, isStaticOnly);
                        requiresValue(right = action[-1]);
                        code.createAndPrependNode(action).setData(left.position, leftType, LOAD_LOCAL, foundLocal);
                        left.setData(before, null, STORE_LOCAL, foundLocal);
                        break label1;
                    }
                case LOAD_STATIC:
                    {
                        Field foundField = (Field) left.operand1;
                        Callable enclosingCallable = parent.parentCode.parentCallable;
                        ClassType enclosingClassType = enclosingCallable.parentType;
                        if(foundField.isFinal() && (!(enclosingCallable instanceof ClassInit) || foundField.parentType != enclosingClassType || foundField.value != null))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundField }
                            )) { source = source, position = before };
                        }
                        leftType = foundField.type;
                        position = parseExpression(action = code.createAndAppendNode(left), source, position + 1, isStaticOnly);
                        requiresValue(right = action[-1]);
                        code.createAndPrependNode(action).setData(left.position, leftType, LOAD_STATIC, foundField);
                        left.setData(before, null, STORE_STATIC, foundField);
                        break label1;
                    }
                case READ_FIELD:
                case READ_SPECIAL:
                case READ_PROPERTY:
                    {
                        TypedMember foundFieldoid = (TypedMember) left.operand1;
                        if(foundFieldoid instanceof Property)
                        {
                            if(!((Property) foundFieldoid).hasWrite())
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.access.property-read-only.write"), new Object[] { foundFieldoid }
                                )) { source = source, position = before };
                            }
                        } else
                        {
                            Node load = left[0];
                            Callable enclosingCallable = parent.parentCode.parentCallable;
                            ClassType enclosingClassType = enclosingCallable.parentType;
                            if(
                                foundFieldoid.isFinal() && (
                                    !(enclosingCallable instanceof InstInit) || foundFieldoid.parentType != enclosingClassType ||
                                    load.instruction != LOAD_LOCAL || load.operand1 != enclosingCallable.arguments.thisArgument
                                )
                            )
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.access.field-final.write"), new Object[] { foundFieldoid }
                                )) { source = source, position = before };
                            }
                        }
                        leftType = foundFieldoid.type;
                        position = parseExpression(action = code.createAndAppendNode(left), source, position + 1, isStaticOnly);
                        requiresValue(right = action[-1]);
                        Node read = code.createAndPrependNode(action).setData(left.position, leftType, instruction, foundFieldoid);
                        code.createAndAppendNode(read).setData(-1, null, DUP1, fldTypeObject);
                        left.setData(before, null, instruction + A_DELTA, foundFieldoid);
                        break label1;
                    }
                case READ_COMPONENT:
                    {
                        leftType = (Type) left.operand1;
                        position = parseExpression(action = code.createAndAppendNode(left), source, position + 1, isStaticOnly);
                        requiresValue(right = action[-1]);
                        Node read = code.createAndPrependNode(action).setData(left.position, leftType, READ_COMPONENT, leftType);
                        code.createAndAppendNode(read).setData(-1, null, DUP2, fldTypeInt);
                        left.setData(before, null, WRITE_COMPONENT, leftType);
                        break label1;
                    }
                case INVOKE_SERVICE:
                case INVOKE_SPECIAL:
                case INVOKE_VIRTUAL:
                    Operator foundReadOperator;
                    TableItem foundCallable = left.operand1;
                    if(foundCallable instanceof Operator && (foundReadOperator = (Operator) foundCallable).kind == READ_COMPONENT)
                    {
                        leftType = foundReadOperator.type;
                        Node load = left[0];
                        ClassType enclosingClassType = parent.parentCode.parentCallable.parentType;
                        ClassType dereferenceClassType = (ClassType) load.type;
                        Type[] arguments = new Type[] { foundReadOperator.arguments[0].type, leftType };
                        Operator[] foundOperators = dereferenceClassType.findOperators(WRITE_COMPONENT, arguments, enclosingClassType);
                        Operator foundWriteOperator = foundOperators == null || foundOperators.length != 1 ? null : foundOperators[0];
                        if(foundWriteOperator == null || !foundWriteOperator.isIdentityArguments(arguments))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("not-found.operator"), new Object[] { dereferenceClassType, Operator.kindToSymbol(WRITE_COMPONENT) + ArgumentArray.toString(arguments) }
                            )) { source = source, position = before };
                        }
                        boolean isUseSuper = load.useSuper;
                        if(!foundWriteOperator.isVisibleFrom(enclosingClassType, isUseSuper ? enclosingClassType : dereferenceClassType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("invisible.operator"), new Object[] { enclosingClassType.specialSimpleName, foundWriteOperator }
                            )) { source = source, position = before };
                        }
                        if(isUseSuper && foundWriteOperator.isAbstract())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.direct-access-abstract.operator"), new Object[] { foundWriteOperator }
                            )) { source = source, position = before };
                        }
                        position = parseExpression(action = code.createAndAppendNode(left), source, position + 1, isStaticOnly);
                        requiresValue(right = action[-1]);
                        Node read = code.createAndPrependNode(action).setData(left.position, leftType, instruction, foundReadOperator);
                        code.createAndAppendNode(read).setData(-1, null, DUP2, arguments[0]);
                        left.setData(before, null, isUseSuper ? INVOKE_SPECIAL : invokeInstructionFor(foundWriteOperator, dereferenceClassType), foundWriteOperator);
                        break label1;
                    }
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("applicable.operator.increment-decrement"), new Object[] { source.getLexemeString(before) }
                )) { source = source, position = before };
            }
            Type rightType = right.type;
            if(!(leftType instanceof PrimitiveType) || !leftType.isBoolean() && !leftType.isNumeric() || !(rightType instanceof PrimitiveType) || !rightType.isBoolean() && !rightType.isNumeric())
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), leftType, rightType }
                )) { source = source, position = before };
            }
            boolean isChar = leftType.isChar();
            Type typeInt = fldTypeInt;
            Type mustType;
            switch(operation)
            {
            case O_SCAL_SHR:
            case O_SCAL_SHRU:
            case O_SCAL_SHL:
            case O_VECT_SHR:
            case O_VECT_SHRU:
            case O_VECT_SHL:
                mustType = typeInt;
                break;
            default:
                mustType = isChar ? typeInt : leftType;
            }
            if(!mustType.isConvertableFrom(rightType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.type"), new Object[] { rightType, mustType }
                )) { source = source, position = before };
            }
            cast(right, mustType);
            int kind = leftType.kind;
            Type resultType;
            label1:
            {
                switch(operation)
                {
                case O_BIT_AND:
                case O_BIT_OR:
                case O_BIT_XOR:
                    if(kind == CHAR)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind == BOOLEAN || kind >= BYTE && kind <= LONG8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_SCAL_MUL:
                case O_SCAL_ADD:
                case O_SCAL_SUB:
                    if(kind == CHAR)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind >= BYTE && kind <= SHORT8)
                    {
                        resultType = getPrimitiveType(INT | kind & 3);
                        break label1;
                    }
                    if(kind >= REAL && kind <= FLOAT8 || kind >= INT && kind <= LONG8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_SCAL_DIV:
                case O_SCAL_DIVU:
                    if(kind == CHAR || kind == BYTE || kind == SHORT)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind >= REAL && kind <= FLOAT8 || kind == INT || kind == LONG)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_SCAL_REM:
                case O_SCAL_REMU:
                    if(kind == CHAR || kind == BYTE || kind == SHORT)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind == REAL || kind == DOUBLE || kind == FLOAT || kind == INT || kind == LONG)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_SCAL_SHR:
                case O_SCAL_SHRU:
                case O_SCAL_SHL:
                    if(kind == CHAR)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind >= BYTE && kind <= SHORT8)
                    {
                        resultType = getPrimitiveType(INT | kind & 3);
                        break label1;
                    }
                    if(kind >= INT && kind <= LONG8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_VECT_MUL:
                case O_VECT_ADD:
                case O_VECT_SUB:
                    if(kind == CHAR)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind >= DOUBLE && kind <= LONG8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_VECT_DIV:
                    if(kind >= DOUBLE && kind <= FLOAT8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_VECT_SHR:
                case O_VECT_SHRU:
                case O_VECT_SHL:
                case O_VECT_GT:
                case O_VECT_GE:
                case O_VECT_LT:
                case O_VECT_LE:
                case O_VECT_EQ:
                case O_VECT_NE:
                    if(kind == CHAR)
                    {
                        resultType = typeInt;
                        break label1;
                    }
                    if(kind >= BYTE && kind <= LONG8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                case O_VECT_HMUL:
                case O_VECT_HMULU:
                case O_VECT_SADD:
                case O_VECT_SADDU:
                case O_VECT_SSUB:
                case O_VECT_SSUBU:
                    if(kind >= BYTE && kind <= SHORT8)
                    {
                        resultType = leftType;
                        break label1;
                    }
                    break;
                default:
                    break label1;
                }
                throw new TextSourceException(String.format(
                    package.getResourceString("not-defined.operator.2"), new Object[] { source.getLexemeString(before), leftType, rightType }
                )) { source = source, position = before };
            }
            action.setData(before, resultType, operation, isChar ? typeInt : leftType);
            cast(action, leftType);
        }
        return position;
    }

    private int parseDeclareLocal(Node parent, TextSource source, int position, boolean isLocalAllowed) throws TextSourceException {
        label0:
        {
            if(isLocalAllowed)
            {
                int kind = source.getLexemeKind(position);
                boolean isFinal = false;
                if(kind == FINAL)
                {
                    isFinal = true;
                    kind = source.getLexemeKind(++position);
                }
                boolean isName = kind == L_NAME;
                if(kind >= VOID && kind < VOID + PRIMITIVES_LENGTH || isName)
                {
                    ImmediateBuilderItemHolder localTypeHolder = getItemHolder();
                    int after = isName ? (
                        tryParseName(parent, source, position, source.getLexemeString(position), localTypeHolder)
                    ) : (
                        tryParseTypeName(source, position, parent.parentCode.parentCallable.parentType, localTypeHolder)
                    );
                    Type localType = localTypeHolder.resultType;
                    if(localType != null && source.getLexemeKind(after) == L_NAME)
                    {
                        position = after;
                        if(localType.isVoid())
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("type.not-suitable.local"), new Object[] { localType }
                            )) { source = source, position = position };
                        }
                        String localName = source.getLexemeString(position);
                        tryParseName(parent, source, position, localName, localTypeHolder);
                        if(localTypeHolder.resultItem instanceof Local)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("duplicate.name.local"), new Object[] { localName }
                            )) { source = source, position = position };
                        }
                        int before = position++;
                        Code code = parent.parentCode;
                        Node declare = code.createAndAppendNode(parent);
                        if(source.getLexemeKind(position) == EQUALS)
                        {
                            position = parseExpression(declare, source, position + 1, false);
                            Node value = declare[-1];
                            requiresValue(value);
                            Type valueType = value.type;
                            if(!localType.isConvertableFrom(valueType))
                            {
                                throw new TextSourceException(String.format(
                                    package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, localType }
                                )) { source = source, position = before + 1 };
                            }
                            cast(value, localType);
                            if(isFinal && value.instruction == LOAD_CONST)
                            {
                                Constant localValue = (Constant) value.operand1;
                                if(!localValue.isReference() || localValue.isReflective() || localValue.isNull())
                                {
                                    declare.setData(before + 1, null, DECLARE_LOCAL, code.createLocal(true, localType, localName, localValue, before));
                                    code.removeNode(value);
                                    break label0;
                                }
                            }
                            declare.setData(before + 1, null, DECLARE_LOCAL, code.createLocal(isFinal, localType, localName, null, before));
                            break label0;
                        }
                        if(isFinal)
                        {
                            throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                        }
                        if(localType instanceof ClassType)
                        {
                            code.createAndAppendNode(declare).setData(-1, localType, LOAD_CONST, fldNull.castTo(localType));
                        }
                        else if(localType.isNumeric())
                        {
                            code.createAndAppendNode(declare).setData(-1, localType, LOAD_CONST, fldConstantFactory.createByte(0).castTo(localType));
                        }
                        else
                        {
                            code.createAndAppendNode(declare).setData(-1, localType, LOAD_CONST, fldFalse);
                        }
                        declare.setData(-1, null, DECLARE_LOCAL, code.createLocal(false, localType, localName, null, before));
                        break label0;
                    }
                }
                if(isFinal)
                {
                    throw new TextSourceException(package.getResourceString("expected.declaration.local")) { source = source, position = position };
                }
            }
            position = parseExpression(parent, source, position, false);
            Code code = parent.parentCode;
            Node value = parent[-1];
            switch(value.instruction)
            {
            case INC_POST_LOAD_LOCAL:
            case INC_PRED_LOAD_LOCAL:
                value.setData(value.position, null, INC_LOCAL, value.operand1);
                break;
            case DEC_POST_LOAD_LOCAL:
            case DEC_PRED_LOAD_LOCAL:
                value.setData(value.position, null, DEC_LOCAL, value.operand1);
                break;
            case INVOKE_STATIC:
                if(!((Callable) value.operand1).type.isVoid()) value.weak = true;
                value.type = null;
                break;
            case INVOKE_SERVICE:
            case INVOKE_SPECIAL:
            case INVOKE_VIRTUAL:
                Callable foundCallable = (Callable) value.operand1;
                if(!(foundCallable instanceof Operator) || ((Operator) foundCallable).kind != WRITE_COMPONENT)
                {
                    if(!foundCallable.type.isVoid()) value.weak = true;
                    value.type = null;
                    break;
                }
                /* падение через */
            case WRITE_COMPONENT:
                Node last = value[-1];
                if(last.instruction == DUP1X2)
                {
                    code.removeNode(last);
                    value.type = null;
                    break;
                }
                if(value.length == 4)
                {
                    if(last.instruction == CAST_TO)
                    {
                        last = last[0];
                    }
                    int instruction = last.instruction;
                    if(instruction == O_SCAL_ADD || instruction == O_VECT_ADD)
                    {
                        Node dup = last[0];
                        if(dup.instruction == DUP1X2)
                        {
                            code.removeNode(dup);
                            code.moveNode(value[-2], last, 0);
                            value.type = null;
                        }
                    }
                }
                break;
            case WRITE_FIELD:
            case WRITE_SPECIAL:
            case WRITE_PROPERTY:
                Node last = value[-1];
                if(last.instruction == DUP1X1)
                {
                    code.removeNode(last);
                    value.type = null;
                    break;
                }
                if(value.length == 3)
                {
                    if(last.instruction == CAST_TO)
                    {
                        last = last[0];
                    }
                    int instruction = last.instruction;
                    if(instruction == O_SCAL_ADD || instruction == O_VECT_ADD)
                    {
                        Node dup = last[0];
                        if(dup.instruction == DUP1X1)
                        {
                            code.removeNode(dup);
                            code.moveNode(value[-2], last, 0);
                            value.type = null;
                        }
                    }
                }
                break;
            case STORE_LOCAL:
            case STORE_STATIC:
                Node last = value[-1];
                if(last.instruction == DUP1)
                {
                    code.removeNode(last);
                    value.type = null;
                    break;
                }
                if(value.length == 2)
                {
                    if(last.instruction == CAST_TO)
                    {
                        last = last[0];
                    }
                    int instruction = last.instruction;
                    if(instruction == O_SCAL_ADD || instruction == O_VECT_ADD)
                    {
                        Node dup = last[0];
                        if(dup.instruction == DUP1)
                        {
                            code.removeNode(dup);
                            code.moveNode(value[-2], last, 0);
                            value.type = null;
                        }
                    }
                }
                break;
            case NEW_INSTANCE:
                Node dup = value[-1][0];
                if(dup.instruction == DUP1)
                {
                    code.removeNode(dup);
                    value.type = null;
                }
                break;
            default:
                throw new TextSourceException(package.getResourceString("expected.invocation-or-assignment")) { source = source, position = position };
            }
        }
        return position;
    }

    private int parseDeclareWith(Node parent, TextSource source, int position, boolean isSynchronized) throws TextSourceException {
        label0:
        {
            {
                int kind = source.getLexemeKind(position);
                boolean isFinal = false;
                if(kind == FINAL)
                {
                    isFinal = true;
                    kind = source.getLexemeKind(++position);
                }
                boolean isName = kind == L_NAME;
                if(kind >= VOID && kind < VOID + PRIMITIVES_LENGTH || isName)
                {
                    ImmediateBuilderItemHolder localTypeHolder = getItemHolder();
                    int after = isName ? (
                        tryParseName(parent, source, position, source.getLexemeString(position), localTypeHolder)
                    ) : (
                        tryParseTypeName(source, position, parent.parentCode.parentCallable.parentType, localTypeHolder)
                    );
                    Type localType = localTypeHolder.resultType;
                    if(localType != null && source.getLexemeKind(after) == L_NAME)
                    {
                        position = after;
                        if(!(localType instanceof ClassType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString(isSynchronized ? "must-be.class-type.local.synchronized" : "must-be.class-type.local.with"), new Object[] { localType, fldTypeObject }
                            )) { source = source, position = position };
                        }
                        String localName = source.getLexemeString(position);
                        tryParseName(parent, source, position, localName, localTypeHolder);
                        if(localTypeHolder.resultItem instanceof Local)
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("duplicate.name.local"), new Object[] { localName }
                            )) { source = source, position = position };
                        }
                        int before = position++;
                        if(source.getLexemeKind(position) != EQUALS)
                        {
                            throw new TextSourceException(package.getResourceString("expected.equals")) { source = source, position = position };
                        }
                        Code code = parent.parentCode;
                        Node declare = code.createAndAppendNode(parent);
                        position = parseExpression(declare, source, position + 1, false);
                        Node value = declare[-1];
                        requiresValue(value);
                        Type valueType = value.type;
                        if(!localType.isConvertableFrom(valueType))
                        {
                            throw new TextSourceException(String.format(
                                package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, localType }
                            )) { source = source, position = before + 1 };
                        }
                        cast(value, localType);
                        if(value.instruction == LOAD_CONST)
                        {
                            Constant localValue = (Constant) value.operand1;
                            if(localValue.isReflective() || localValue.isNull())
                            {
                                declare.setData(before + 1, null, isSynchronized ? DECLARE_LOCAL : DECLARE_WITH, code.createLocal(true, localType, localName, localValue, before));
                                code.removeNode(value);
                                break label0;
                            }
                        }
                        declare.setData(before + 1, null, isSynchronized ? DECLARE_LOCAL : DECLARE_WITH, code.createLocal(true, localType, localName, null, before));
                        break label0;
                    }
                }
                if(isFinal)
                {
                    throw new TextSourceException(package.getResourceString("expected.declaration.local")) { source = source, position = position };
                }
            }
            Code code = parent.parentCode;
            Node declare = code.createAndAppendNode(parent);
            position = parseExpression(declare, source, position, false);
            Node value = declare[-1];
            requiresValue(value);
            Type valueType = value.type;
            if(!(valueType instanceof ClassType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString(isSynchronized ? "must-be.class-type.expression.synchronized" : "must-be.class-type.expression.with"), new Object[] { valueType, fldTypeObject }
                )) { source = source, position = position };
            }
            if(value.instruction == LOAD_CONST)
            {
                Constant localValue = (Constant) value.operand1;
                if(localValue.isReflective() || localValue.isNull())
                {
                    if(isSynchronized)
                    {
                        declare.setData(-1, null, DECLARE_LOCAL, code.createMonitorLocal((ClassType) valueType, localValue));
                    } else
                    {
                        declare.setData(-1, null, DECLARE_WITH, code.createWithLocal((ClassType) valueType, localValue));
                    }
                    code.removeNode(value);
                    break label0;
                }
            }
            if(isSynchronized)
            {
                declare.setData(-1, null, DECLARE_LOCAL, code.createMonitorLocal((ClassType) valueType, null));
            } else
            {
                declare.setData(-1, null, DECLARE_WITH, code.createWithLocal((ClassType) valueType, null));
            }
        }
        return position;
    }

    private int parseBlock(Node control, TextSource source, int position) throws TextSourceException {
        label0: if(source.getLexemeKind(position) != CURLY_CLOSED) do
        {
            switch(source.getLexemeKind(position = parseControl(control, source, position)))
            {
            case L_END:
                throw new TextSourceException(package.getResourceString("expected.closed-curly")) { source = source, position = position };
            case CURLY_CLOSED:
                break label0;
            }
        } while(true);
        return position + 1;
    }

    private int parseBreak(Node control, TextSource source, int position) throws TextSourceException {
        label0:
        {
            if(source.getLexemeKind(position) != L_NAME)
            {
                /* без метки */
                for(Node node = control.parentNode; node != null; node = node.parentNode) switch(node.instruction)
                {
                case FINALLY_ENTER:
                    throw new TextSourceException(package.getResourceString("can-not-transfer.outside-finally")) { source = source, position = position };
                case DO:
                case FOR:
                case WHILE:
                case SWITCH:
                    control.setData(control.position, BREAK, node);
                    break label0;
                }
                throw new TextSourceException(package.getResourceString("can-not-use.break")) { source = source, position = position };
            }
            /* с меткой */
            Object labelName = source.getLexemeString(position);
            for(Node node = control.parentNode; node != null; node = node.parentNode) switch(node.instruction)
            {
            case FINALLY_ENTER:
                throw new TextSourceException(package.getResourceString("can-not-transfer.outside-finally")) { source = source, position = position };
            case LABEL:
                if(labelName.equals(node.reference1))
                {
                    control.setData(control.position, BREAK, node);
                    position++;
                    break label0;
                }
            }
            throw new TextSourceException(String.format(
                package.getResourceString("not-found.label"), new Object[] { labelName }
            )) { source = source, position = position };
        }
        /* точка с запятой */
        if(source.getLexemeKind(position) != SEMICOLON)
        {
            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
        }
        return position + 1;
    }

    private int parseContinue(Node control, TextSource source, int position) throws TextSourceException {
        label0:
        {
            if(source.getLexemeKind(position) != L_NAME)
            {
                /* без метки */
                for(Node node = control.parentNode; node != null; node = node.parentNode) switch(node.instruction)
                {
                case FINALLY_ENTER:
                    throw new TextSourceException(package.getResourceString("can-not-transfer.outside-finally")) { source = source, position = position };
                case DO:
                case FOR:
                case WHILE:
                    control.setData(control.position, CONTINUE, node);
                    break label0;
                }
                throw new TextSourceException(package.getResourceString("can-not-use.continue")) { source = source, position = position };
            }
            /* с меткой */
            Object labelName = source.getLexemeString(position);
            for(Node node = control.parentNode; node != null; node = node.parentNode) switch(node.instruction)
            {
            case FINALLY_ENTER:
                throw new TextSourceException(package.getResourceString("can-not-transfer.outside-finally")) { source = source, position = position };
            case LABEL:
                if(labelName.equals(node.reference1))
                {
                    int instruction = (node = node[0]).instruction;
                    if(instruction != DO && instruction != FOR && instruction != WHILE)
                    {
                        throw new TextSourceException(package.getResourceString("can-not-use.continue")) { source = source, position = position };
                    }
                    control.setData(control.position, CONTINUE, node);
                    position++;
                    break label0;
                }
            }
            throw new TextSourceException(String.format(
                package.getResourceString("not-found.label"), new Object[] { labelName }
            )) { source = source, position = position };
        }
        /* точка с запятой */
        if(source.getLexemeKind(position) != SEMICOLON)
        {
            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
        }
        return position + 1;
    }

    private int parseDo(Node control, TextSource source, int position) throws TextSourceException {
        /* тело цикла */
        if(source.getLexemeKind(position = parseControl(control, source, position)) != WHILE)
        {
            throw new TextSourceException(package.getResourceString("expected.while")) { source = source, position = position };
        }
        /* условие повтора */
        if(source.getLexemeKind(++position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        position = parseExpression(control, source, position + 1, false);
        Node condition = control[-1];
        requiresValue(condition);
        Type conditionType = condition.type;
        if(!conditionType.isBoolean())
        {
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-use.expression.repeat-condition"), new Object[] { conditionType, fldTypeBoolean }
            )) { source = source, position = position };
        }
        if(source.getLexemeKind(position) != PARENTH_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
        }
        /* точка с запятой */
        if(source.getLexemeKind(++position) != SEMICOLON)
        {
            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
        }
        return position + 1;
    }

    private int parseFor(Node control, TextSource source, int position) throws TextSourceException {
        /* инициализация */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        label0: if(source.getLexemeKind(++position) != SEMICOLON) do
        {
            switch(source.getLexemeKind(position = parseDeclareLocal(control, source, position, true)))
            {
            default:
                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
            case SEMICOLON:
                break label0;
            case COMMA:
                position++;
            }
        } while(true);
        Code code = control.parentCode;
        code.createAndAppendNode(control).setData(-1, JUMP);
        /* условие повтора */
        Node condition;
        if(source.getLexemeKind(++position) == SEMICOLON)
        {
            condition = code.createAndAppendNode(control).setData(-1, fldTypeBoolean, LOAD_CONST, fldTrue);
        } else
        {
            position = parseExpression(control, source, position, false);
            requiresValue(condition = control[-1]);
            Type conditionType = condition.type;
            if(!conditionType.isBoolean())
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-use.expression.repeat-condition"), new Object[] { conditionType, fldTypeBoolean }
                )) { source = source, position = position };
            }
            if(source.getLexemeKind(position) != SEMICOLON)
            {
                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
            }
        }
        /* шаг */
        Node step = code.createAndAppendNode(control).setData(-1, BLOCK);
        label0: if(source.getLexemeKind(++position) != PARENTH_CLOSED) do
        {
            switch(source.getLexemeKind(position = parseDeclareLocal(step, source, position, false)))
            {
            default:
                throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
            case PARENTH_CLOSED:
                break label0;
            case COMMA:
                position++;
            }
        } while(true);
        /* тело цикла */
        position = parseControl(control, source, position + 1);
        /* перестановка узлов */
        int index = control.length;
        code.moveNode(step, index);
        code.moveNode(condition, index);
        return position;
    }

    private int parseIf(Node control, TextSource source, int position) throws TextSourceException {
        /* условие ветвления */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        position = parseExpression(control, source, position + 1, false);
        Node condition = control[-1];
        requiresValue(condition);
        Type conditionType = condition.type;
        if(!conditionType.isBoolean())
        {
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-use.expression.branch-condition"), new Object[] { conditionType, fldTypeBoolean }
            )) { source = source, position = position };
        }
        if(source.getLexemeKind(position) != PARENTH_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
        }
        /* ветка «тогда» */
        if(source.getLexemeKind(position = parseControl(control, source, position + 1)) == ELSE)
        {
            /* ветка «иначе» */
            control.parentCode.createAndAppendNode(control).setData(-1, JUMP).special = true;
            position = parseControl(control, source, position + 1);
        }
        return position;
    }

    private int parseReturn(Node control, TextSource source, int position) throws TextSourceException {
        Type targetType = control.parentCode.parentCallable.type;
        if(!targetType.isVoid())
        {
            position = parseExpression(control, source, position, false);
            Node value = control[-1];
            requiresValue(value);
            Type valueType = value.type;
            if(!targetType.isConvertableFrom(valueType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.type"), new Object[] { valueType, targetType }
                )) { source = source, position = position };
            }
            cast(value, targetType);
        }
        for(Node node = control.parentNode; node != null; node = node.parentNode) if(node.instruction == FINALLY_ENTER)
        {
            throw new TextSourceException(package.getResourceString("can-not-transfer.outside-finally")) { source = source, position = position };
        }
        if(source.getLexemeKind(position) != SEMICOLON)
        {
            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
        }
        return position + 1;
    }

    private int parseSwitch(Node control, TextSource source, int position) throws TextSourceException {
        /* выражение ветвления */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        Code code = control.parentCode;
        Node branch = code.createAndAppendNode(control).setData(-1, BRANCH);
        position = parseExpression(branch, source, position + 1, false);
        Node target = branch[-1];
        requiresValue(target);
        Type targetType = target.type;
        if(!targetType.isInt())
        {
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-use.expression.branch-switch"), new Object[] { targetType, fldTypeInt }
            )) { source = source, position = position };
        }
        if(source.getLexemeKind(position) != PARENTH_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
        }
        /* тело ветвления */
        if(source.getLexemeKind(++position) != CURLY_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
        }
        label0: for(position++, Node label = null, int[] labels = new int[0x1f], boolean ldefault = false, int llength = 0; ; ) switch(source.getLexemeKind(position))
        {
        case CURLY_CLOSED:
            if(!ldefault) code.createAndAppendNode(control).setData(position, DEFAULT);
            break label0;
        case CASE:
            int before = position++;
            position = parseExpression(control, source, position, false);
            if((label = control[-1]).instruction != LOAD_CONST)
            {
                throw new TextSourceException(package.getResourceString("must-be.constant.case-label")) { source = source, position = position };
            }
            Type labelType = label.type;
            if(!targetType.isConvertableFrom(labelType))
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("can-not-be.converted.type"), new Object[] { labelType, targetType }
                )) { source = source, position = position };
            }
            int labelValue = ((Constant) label.operand1).asInt();
            if(llength > 0 && Array.indexOf(labelValue, labels, 0, llength) >= 0)
            {
                throw new TextSourceException(String.format(
                    package.getResourceString("duplicate.label.case"), new Object[] { Int.toString(labelValue) }
                )) { source = source, position = position };
            }
            if(source.getLexemeKind(position) != COLON)
            {
                throw new TextSourceException(package.getResourceString("expected.colon")) { source = source, position = position };
            }
            if(llength == labels.length) Array.copy(labels, 0, labels = new int[llength << 1 | 1], 0, llength);
            label.setData(before, CASE, new Int(labelValue));
            labels[llength++] = labelValue;
            position++;
            break;
        case DEFAULT:
            int before = position++;
            if(ldefault)
            {
                throw new TextSourceException(package.getResourceString("duplicate.label.default")) { source = source, position = position };
            }
            if(source.getLexemeKind(position) != COLON)
            {
                throw new TextSourceException(package.getResourceString("expected.colon")) { source = source, position = position };
            }
            label = code.createAndAppendNode(control).setData(before, DEFAULT);
            ldefault = true;
            position++;
            break;
        default:
            if(label == null)
            {
                throw new TextSourceException(package.getResourceString("expected.case-or-default")) { source = source, position = position };
            }
            position = parseControl(label, source, position);
        }
        return position + 1;
    }

    private int parseSynchronized(Node control, TextSource source, int position) throws TextSourceException {
        boolean isSynchronizedWith = false;
        if(source.getLexemeKind(position) == WITH)
        {
            isSynchronizedWith = true;
            position++;
        }
        /* переменная синхронизации */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        position = parseDeclareWith(control, source, position + 1, !isSynchronizedWith);
        Local monitor = (Local) control[-1].operand1;
        ClassType typeObject = fldTypeObject;
        Code code = control.parentCode;
        Node enter = code.createAndAppendNode(control).setData(-1, MONITOR_ENTER);
        Constant value = monitor.value;
        boolean isConstant = monitor.isConstant();
        if(isConstant)
        {
            code.createAndAppendNode(enter).setData(-1, typeObject, LOAD_CONST, value);
        } else
        {
            code.createAndAppendNode(enter).setData(-1, typeObject, LOAD_LOCAL, monitor);
        }
        if(source.getLexemeKind(position) != PARENTH_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
        }
        /* тело синхронизации */
        if(source.getLexemeKind(++position) != CURLY_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
        }
        control = code.createAndAppendNode(control).setData(-1, TRY);
        Node blockTry = code.createAndAppendNode(control).setData(-1, BEGIN);
        position = parseBlock(blockTry, source, position + 1) - 1;
        blockTry = code.createAndAppendNode(blockTry).setData(-1, END);
        Node blockFinally = code.createAndAppendNode(control).setData(-1, FINALLY_ENTER);
        Node leave = code.createAndAppendNode(blockFinally).setData(-1, MONITOR_LEAVE);
        if(isConstant)
        {
            code.createAndAppendNode(leave).setData(-1, typeObject, LOAD_CONST, value);
        } else
        {
            code.createAndAppendNode(leave).setData(-1, typeObject, LOAD_LOCAL, monitor);
        }
        code.createAndAppendNode(blockFinally).setData(-1, FINALLY_LEAVE).special = true;
        code.createAndAppendNode(blockTry).setData(-1, INVOKE_FINALLY, blockFinally).special = true;
        code.createAndAppendNode(blockTry).setData(-1, JUMP).special = true;
        return position + 1;
    }

    private int parseThrow(Node control, TextSource source, int position) throws TextSourceException {
        /* выражение */
        position = parseExpression(control, source, position, false);
        Node target = control[-1];
        requiresValue(target);
        Type targetType = target.type;
        Type typeThrowable = fldTypeThrowable;
        if(!typeThrowable.isConvertableFrom(targetType))
        {
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-be.thrown"), new Object[] { targetType, typeThrowable }
            )) { source = source, position = position };
        }
        /* точка с запятой */
        if(source.getLexemeKind(position) != SEMICOLON)
        {
            throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
        }
        control.setData(control.position, THROW, targetType);
        return position + 1;
    }

    private int parseTry(Node control, TextSource source, int position) throws TextSourceException {
        /* проверка на вложение в блок finally */
        for(Node node = control.parentNode; node != null; node = node.parentNode) if(node.instruction == FINALLY_ENTER)
        {
            throw new TextSourceException(package.getResourceString("can-not-be.try-inside-finally")) { source = source, position = position - 1 };
        }
        /* тело блока */
        if(source.getLexemeKind(position) != CURLY_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
        }
        Code code = control.parentCode;
        Node blockTry = code.createAndAppendNode(control).setData(position, BEGIN);
        position = parseBlock(blockTry, source, position + 1);
        (blockTry = code.createAndAppendNode(blockTry).setData(-1, END));
        switch(source.getLexemeKind(position))
        {
        case CATCH:
            Node blockCatch = null;
            Node parent = control.parentNode;
            ClassType typeThrowable = fldTypeThrowable;
            ClassType enclosing = code.parentCallable.parentType;
            ImmediateBuilderItemHolder localTypeHolder = getItemHolder();
            do
            {
                /* тело блока catch */
                int block = position;
                if(blockCatch != null)
                {
                    code.createAndAppendNode(blockCatch).setData(-1, JUMP).special = true;
                }
                if(source.getLexemeKind(++position) != PARENTH_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != L_NAME)
                {
                    throw new TextSourceException(package.getResourceString("expected.name.exception.type")) { source = source, position = position };
                }
                position = parseTypeName(source, position, enclosing, localTypeHolder);
                Type localType = localTypeHolder.resultType;
                if(!typeThrowable.isConvertableFrom(localType))
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("can-not-be.thrown"), new Object[] { localType, typeThrowable }
                    )) { source = source, position = position };
                }
                if(source.getLexemeKind(position) != L_NAME)
                {
                    throw new TextSourceException(package.getResourceString("expected.name.exception.local")) { source = source, position = position };
                }
                int before = position;
                String localName = source.getLexemeString(position);
                tryParseName(parent, source, position, localName, localTypeHolder);
                if(localTypeHolder.resultItem instanceof Local)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("duplicate.name.local"), new Object[] { localName }
                    )) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != PARENTH_CLOSED)
                {
                    throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
                }
                if(source.getLexemeKind(++position) != CURLY_OPENED)
                {
                    throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
                }
                blockCatch = code.createAndAppendNode(control).setData(block, CATCH, localType);
                code.createAndAppendNode(blockCatch).setData(-1, null, DECLARE_LOCAL, code.createLocal(true, localType, localName, null, before));
            } while(source.getLexemeKind(position = parseBlock(blockCatch, source, position + 1)) == CATCH);
            code.createAndAppendNode(blockTry).setData(-1, JUMP).special = true;
            break;
        case FINALLY:
            /* тело блока finally */
            if(source.getLexemeKind(++position) != CURLY_OPENED)
            {
                throw new TextSourceException(package.getResourceString("expected.opened-curly")) { source = source, position = position };
            }
            Node blockFinally = code.createAndAppendNode(control).setData(-1, FINALLY_ENTER);
            position = parseBlock(blockFinally, source, position + 1);
            code.createAndAppendNode(blockFinally).setData(-1, FINALLY_LEAVE).special = true;
            code.createAndAppendNode(blockTry).setData(-1, INVOKE_FINALLY, blockFinally).special = true;
            code.createAndAppendNode(blockTry).setData(-1, JUMP).special = true;
            break;
        default:
            throw new TextSourceException(package.getResourceString("expected.catch-or-finally")) { source = source, position = position };
        }
        return position;
    }

    private int parseWhile(Node control, TextSource source, int position) throws TextSourceException {
        /* условие повтора */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        position = parseExpression(control, source, position + 1, false);
        Node condition = control[-1];
        requiresValue(condition);
        Type conditionType = condition.type;
        if(!conditionType.isBoolean())
        {
            throw new TextSourceException(String.format(
                package.getResourceString("can-not-use.expression.repeat-condition"), new Object[] { conditionType, fldTypeBoolean }
            )) { source = source, position = position };
        }
        if(source.getLexemeKind(position) != PARENTH_CLOSED)
        {
            throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
        }
        /* тело цикла */
        position = parseControl(control, source, position + 1);
        Code code = control.parentCode;
        code.moveNode(condition, control.length);
        code.createAndPrependNode(control).setData(-1, JUMP);
        return position;
    }

    private int parseWith(Node control, TextSource source, int position) throws TextSourceException {
        /* переменные ссылочного типа для быстрого доступа к членам их типов */
        if(source.getLexemeKind(position) != PARENTH_OPENED)
        {
            throw new TextSourceException(package.getResourceString("expected.opened-parenth")) { source = source, position = position };
        }
        label0: for(position++; ; )
        {
            switch(source.getLexemeKind(position = parseDeclareWith(control, source, position, false)))
            {
            default:
                throw new TextSourceException(package.getResourceString("expected.closed-parenth")) { source = source, position = position };
            case PARENTH_CLOSED:
                break label0;
            case COMMA:
                position++;
            }
        }
        /* тело с быстрым доступом к членам типов переменных */
        return parseControl(control, source, position + 1);
    }

    private int parseControl(Node parent, TextSource source, int position) throws TextSourceException {
        Code code = parent.parentCode;
        for(; source.getLexemeKind(position) == L_NAME && source.getLexemeKind(position + 1) == COLON; position += 2)
        {
            parent = code.createAndAppendNode(parent).setData(position, LABEL, source.getLexemeString(position));
        }
        switch(source.getLexemeKind(position))
        {
        case SEMICOLON:
            code.createAndAppendNode(parent).setData(position++, BLOCK);
            break;
        case CURLY_OPENED:
            position = parseBlock(code.createAndAppendNode(parent).setData(position++, BLOCK), source, position);
            break;
        case BREAK:
            position = parseBreak(code.createAndAppendNode(parent).setData(position++, BREAK, null), source, position);
            break;
        case CONTINUE:
            position = parseContinue(code.createAndAppendNode(parent).setData(position++, CONTINUE, null), source, position);
            break;
        case DO:
            position = parseDo(code.createAndAppendNode(parent).setData(position++, DO), source, position);
            break;
        case FOR:
            position = parseFor(code.createAndAppendNode(parent).setData(position++, FOR), source, position);
            break;
        case IF:
            position = parseIf(code.createAndAppendNode(parent).setData(position++, IF), source, position);
            break;
        case RETURN:
            position = parseReturn(code.createAndAppendNode(parent).setData(position++, RETURN), source, position);
            break;
        case SWITCH:
            position = parseSwitch(code.createAndAppendNode(parent).setData(position++, SWITCH), source, position);
            break;
        case SYNCHRONIZED:
            position = parseSynchronized(code.createAndAppendNode(parent).setData(position++, BLOCK), source, position);
            break;
        case THROW:
            position = parseThrow(code.createAndAppendNode(parent).setData(position++, THROW, null), source, position);
            break;
        case TRY:
            position = parseTry(code.createAndAppendNode(parent).setData(position++, TRY), source, position);
            break;
        case WHILE:
            position = parseWhile(code.createAndAppendNode(parent).setData(position++, WHILE), source, position);
            break;
        case WITH:
            position = parseWith(code.createAndAppendNode(parent).setData(position++, BLOCK), source, position);
            break;
        default:
            if(source.getLexemeKind(position = parseDeclareLocal(parent, source, position, true)) != SEMICOLON)
            {
                throw new TextSourceException(package.getResourceString("expected.semicolon")) { source = source, position = position };
            }
            position++;
        }
        return position;
    }

    private int tryParseName(Node parent, TextSource source, int position, String name, ImmediateBuilderItemHolder parsed) {
        Callable enclosingCallable = parent.parentCode.parentCallable;
        ClassType enclosingClassType = enclosingCallable.parentType;
        TableItem resultItem = null;
        Local resultWith = null;
        label0:
        {
            /* поиск среди локальных переменных */
            do for(int index = parent.length; index-- > 0; )
            {
                Node child = parent[index];
                switch(child.instruction)
                {
                case DECLARE_WITH:
                    Local local = (Local) child.operand1;
                    if((resultItem = ((ClassType) local.type).resolveName(name, enclosingClassType, true)) != null)
                    {
                        resultWith = local;
                        break label0;
                    }
                    /* падение через */
                case DECLARE_LOCAL:
                    Local local = (Local) child.operand1;
                    if(name.equals(local.specialSimpleName))
                    {
                        resultItem = local;
                        break label0;
                    }
                }
            } while((parent = parent.parentNode) != null);
            /* поиск среди аргументов метода */
            {
                Local local = enclosingCallable.getArgument(name);
                if(local != null)
                {
                    resultItem = local;
                    break label0;
                }
            }
            /* поиск среди членов типа */
            if((resultItem = enclosingClassType.resolveName(name, enclosingClassType, true)) != null)
            {
                resultWith = enclosingCallable.arguments.thisArgument;
                break label0;
            }
            /* поиск среди типов и пакетов */
            if(name.length <= 0 || name[0] != '<')
            {
                int after = tryParseTypeName(source, position, enclosingClassType, parsed);
                return parsed.resultType != null ? after : tryParsePackageName(source, position, enclosingClassType, parsed);
            }
        }
        parsed.resultWith = resultWith;
        parsed.resultItem = resultItem;
        return position + 1;
    }

    private int tryParsePackageName(TextSource source, int position, ClassType enclosing, PackageHolder parsed) {
        if(source.getLexemeKind(position) != L_NAME)
        {
            parsed.resultPack = null;
            return position;
        }
        Package result;
        {
            String name = source.getLexemeString(position++);
            /* последние позиция и результат */
            int lastPosition = position;
            Package lastResult = result = getPackage(name);
            /* распознавание канонического имени пакета */
            StringBuilder specialCanonicalName = new StringBuilder(LIMIT_NAME_LENGTH) + name;
            while(source.getLexemeKind(position) == PERIOD && source.getLexemeKind(position + 1) == L_NAME)
            {
                position++;
                if((result = getPackage((specialCanonicalName + '.' + source.getLexemeString(position++)).toString())) != null)
                {
                    lastPosition = position;
                    lastResult = result;
                }
            }
            if(result == null)
            {
                position = lastPosition;
                result = lastResult;
            }
        }
        parsed.resultPack = result;
        return position;
    }

    private int tryParseClassName(TextSource source, int position, ClassType enclosing, TypeHolder parsed) {
        if(source.getLexemeKind(position) != L_NAME)
        {
            parsed.resultType = null;
            return position;
        }
        ClassType result;
        label0:
        {
            String name = source.getLexemeString(position++);
            /* поиск среди типов в исходном коде */
            if((result = source.getDeclaredType(name)) != null) break label0;
            if((result = source.getImportedType(name)) != null) break label0;
            /* поиск в родительском пакете */
            if((result = (ClassType) source.owner.getChildType(name)) != null && result.isVisibleFrom(enclosing)) break label0;
            /* поиск среди неявно импортированных типов */
            ClassType[] types = source.findImplicitlyImportedTypes(name, enclosing);
            int length = types.length;
            if(length > 0 && (result = types[0]).isVisibleFrom(enclosing))
            {
                if(length > 1) result = null;
                break label0;
            }
            /* поиск в языковом пакете */
            if((result = (ClassType) getLanguagePackage().getChildType(name)) != null && result.isVisibleFrom(enclosing)) break label0;
            /* распознавание канонического имени типа */
            StringBuilder specialCanonicalName = new StringBuilder(LIMIT_NAME_LENGTH) + name;
            while(source.getLexemeKind(position) == PERIOD)
            {
                if(source.getLexemeKind(++position) != L_NAME)
                {
                    result = null;
                    break label0;
                }
                if((result = getClassType((specialCanonicalName + '.' + source.getLexemeString(position++)).toString())) != null) break label0;
            }
            result = null;
        }
        if(!parsed.helpersAllowed && result != null && result.isHelper()) result = null;
        parsed.resultType = result;
        return position;
    }

    private int tryParseTypeName(TextSource source, int position, ClassType enclosing, TypeHolder parsed) {
        int kind = source.getLexemeKind(position);
        if(kind == VOID)
        {
            parsed.resultType = getPrimitiveType(VOID);
            return position + 1;
        }
        Type result;
        if(kind > VOID && kind < VOID + PRIMITIVES_LENGTH && isPrimitiveKind(kind))
        {
            position++;
            result = getPrimitiveType(kind);
        } else
        {
            position = tryParseClassName(source, position, enclosing, parsed);
            if((result = parsed.resultType) == null || result.isHelper())
            {
                parsed.resultType = result;
                return position;
            }
        }
        for(int dimCount = 0; dimCount < LIMIT_DIMENSIONS_COUNT && source.getLexemeKind(position) == BRACKET_OPENED && source.getLexemeKind(position + 1) == BRACKET_CLOSED; position += 2, dimCount++)
        {
            result = acquireArrayType(result);
        }
        parsed.resultType = result;
        return position;
    }

    private Node appendIncrementCode(Node parent, PrimitiveType argumentType, boolean isUseIncrement) {
        Node result;
        Code code = parent.parentCode;
        switch(argumentType.kind)
        {
        default:
            Constant delta = fldConstantFactory.createByte(isUseIncrement ? 1 : -1).castTo(argumentType);
            result = code.createAndAppendNode(parent).setData(-1, argumentType, O_VECT_ADD, argumentType);
            code.createAndAppendNode(result).setData(-1, argumentType, LOAD_CONST, delta);
            break;
        case REAL:
            Constant delta = fldConstantFactory.createReal(isUseIncrement ? 1.0 : -1.0);
            result = code.createAndAppendNode(parent).setData(-1, argumentType, O_SCAL_ADD, argumentType);
            code.createAndAppendNode(result).setData(-1, argumentType, LOAD_CONST, delta);
            break;
        case CHAR:
            Type typeInt = fldTypeInt;
            Constant delta = fldConstantFactory.createInt(isUseIncrement ? 1 : -1);
            result = code.createAndAppendNode(parent).setData(-1, argumentType, CAST_TO, argumentType, typeInt);
            result = code.createAndAppendNode(result).setData(-1, typeInt, O_SCAL_ADD, typeInt);
            code.createAndAppendNode(result).setData(-1, typeInt, LOAD_CONST, delta);
        }
        return result;
    }

    private TableItem getAdditionalOperand(int operand, Hashtable locals, Object[] constants, int index) {
        switch(operand)
        {
        default:
            return null;
        case OPERAND_CONSTANT:
            Object element = constants[index];
            return fldConstantFactory.createFrom(!(element instanceof RecompilableElement) ? element : ((RecompilableElement) element).getItem());
        case OPERAND_LOCAL:
            return (Local) locals.operator [](index <= 0 ? SPECNAME_THIS : (String) constants[index]);
        case OPERAND_GLOBAL:
            return ((FieldElement) constants[index]).getItem();
        }
    }

    private ImmediateBuilderItemHolder getItemHolder() {
        CompilerParallelWorker threadItemHolder = fldThreadItemHolder;
        return threadItemHolder == null ? fldGlobalItemHolder : (ImmediateBuilderItemHolder) threadItemHolder.threadObject();
    }
}

final class ImmediateBuilderForBinarySources(Object, CompilerRunnable)
{
    private final ImmediateBuilder fldParent;

    public (ImmediateBuilder parent) { fldParent = parent; }

    public void run(Object target) throws BinarySourceException, IOException {
        ClassType enclosing = (ClassType) target;
        int length = enclosing.length;
        for(ImmediateBuilder parent = fldParent, int index = 0; index < length; index++)
        {
            Member member = enclosing[index];
            if(member instanceof Callable) parent.readCallableBody((Callable) member);
        }
    }
}

final class ImmediateBuilderForTextSources(Object, CompilerRunnable, CompilerThreadObjectCreator, AVTOOConstants)
{
    private final ImmediateBuilder fldParent;

    public (ImmediateBuilder parent) { fldParent = parent; }

    public void run(Object target) throws TextSourceException {
        ClassType enclosing = (ClassType) target;
        int length = enclosing.length;
        for(ImmediateBuilder parent = fldParent, int index = 0; index < length; index++)
        {
            Member member = enclosing[index];
            if(member instanceof Callable) parent.parseCallableBody((Callable) member);
        }
        for(int index = 0; index < length; index++)
        {
            Member member = enclosing[index];
            if(member instanceof InstInit) for(InstInit thisConstructor = (InstInit) member, int position = -1; ; )
            {
                Node constructor = thisConstructor.code.root[0];
                if(constructor.instruction != INVOKE_SPECIAL) break;
                Callable callable = (Callable) constructor.operand1;
                if(!(callable instanceof InstInit) || callable.parentType != enclosing)
                {
                    break;
                }
                if(position < 0)
                {
                    position = constructor.position;
                }
                if(callable == member)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("constructor.recursive-invocation"), new Object[] { member }
                    )) { source = (TextSource) enclosing.source, position = position };
                }
                thisConstructor = (InstInit) callable;
            }
        }
    }

    public ImmediateBuilderItemHolder createThreadObject() { return new ImmediateBuilderItemHolder(); }
}

class ImmediateBuilderItemHolder(Object, OperatorHolder, TypeHolder, PackageHolder)
{
    protected boolean fldHelpersAllowed;
    protected int fldResultKind;
    protected Type fldResultType;
    protected Package fldResultPack;
    protected Local fldResultWith;
    protected TableItem fldResultItem;

    public () {  }

    public int resultKind { read = fldResultKind, write = fldResultKind }

    public boolean helpersAllowed { read = fldHelpersAllowed, write = fldHelpersAllowed }

    public Type resultType { read = fldResultType, write = setResultType }

    public Package resultPack { read = fldResultPack, write = setResultPack }

    public Local resultWith { read = fldResultWith, write = fldResultWith }

    public TableItem resultItem { read = fldResultItem, write = setResultItem }

    protected void setResultType(Type newResultType) {
        fldResultType = newResultType;
        fldResultPack = null;
        fldResultWith = null;
        fldResultItem = newResultType;
    }

    protected void setResultPack(Package newResultPack) {
        fldResultType = null;
        fldResultPack = newResultPack;
        fldResultWith = null;
        fldResultItem = newResultPack;
    }

    protected void setResultItem(TableItem newResultItem) {
        fldResultType = !(newResultItem instanceof Type) ? null : (Type) newResultItem;
        fldResultPack = !(newResultItem instanceof Package) ? null : (Package) newResultItem;
        fldResultItem = newResultItem;
    }
}

final class ImmediateBuilderUnaryOperation(Object)
{
    private final int fldPosition;
    private final int fldOperation;
    private final Type fldNewType;

    public (int position, int operation) {
        fldPosition = position;
        fldOperation = operation;
    }

    public (int position, int operation, Type newType) {
        fldPosition = position;
        fldOperation = operation;
        fldNewType = newType;
    }

    public int position { read = fldPosition }

    public int operation { read = fldOperation }

    public Type newType { read = fldNewType }
}