ImmediateBuilder.avt

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

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

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

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Стандартной общественной лицензии 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) break;
                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 () {
        fldGlobalItemHolder = new ImmediateBuilderItemHolder();
    }

    public (boolean staticFieldsOnly) {
        fldStaticFieldsOnly = staticFieldsOnly;
        fldGlobalItemHolder = new ImmediateBuilderItemHolder();
    }

    public (boolean staticFieldsOnly, boolean library) {
        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 mlength = type.length, int mindex = 0; mindex < mlength; 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 mlength = type.length, int mindex = 0; mindex < mlength; 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 mlength = type.length, int mindex = 0; mindex < mlength; mindex++)
            {
                Member member = type[mindex];
                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;
        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;
        label0: if(source != null && callable.specialSimpleName.indexOf('.') < 0)
        {
            int position = callable.implementationPosition;
            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 THIS : place = enclosing; break;
                        case SUPER: place = enclosing.getSuperclassType(); 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);
        }
        if(code == null) return;
        Node root = code.root;
        /* проверка обязательной обработки исключений */
        label0: for(Node node = root, Node parent = null, int index = -1; ; )
        {
            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);
        }
        /* подготовка к дальнейшей работе с кодом */
        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)).append(factEnclosing.specialCanonicalName).append('.').append(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)).append(factEnclosing.specialCanonicalName).append('.').append(name).append(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)).append(factEnclosing.specialCanonicalName).append('.').append(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)).append(factEnclosing.specialCanonicalName).append('.').append(name).append(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.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)).append(factEnclosing.specialCanonicalName).append('.').append(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)).append(factEnclosing.specialCanonicalName).append('.').append(name).append(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)).append(factEnclosing.specialCanonicalName).append('.').append(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)).append(factEnclosing.specialCanonicalName).append('.').append(name).append(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)).append(dereferenceClassType.specialCanonicalName).append('.').append(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(kind != 0 || 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)).append(dereferenceClassType.specialCanonicalName).append('.').append(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;
                    if(length <= 0) switch(kind)
                    {
                        case O_SCAL_ADD: kind = O_SCAL_POS; break;
                        case O_SCAL_SUB: kind = O_SCAL_NEG; break;
                        case O_VECT_ADD: kind = O_VECT_POS; break;
                        case O_VECT_SUB: kind = O_VECT_NEG; break;
                    }
                    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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(kind)).append(foundCallable.arguments)
                            }
                        ) : String.format(
                            package.getResourceString("ambiguous.method"),
                            new Object[] { (new StringBuilder(0x0400)).append(dereferenceClassType).append('.').append(name).append(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)).
                                    append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(INVOKE_VIRTUAL)).append(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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(READ_COMPONENT)).append(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) break;
                            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.assignment"), 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)).append(objectResultType.specialCanonicalName).append('.').append(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 };
                        }
                    }
                } 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)
                {
                    ClassType foundClassType = (ClassType) foundItem;
                    if(!foundClassType.isVisibleFrom(enclosingClassType))
                    {
                        throw new TextSourceException(String.format(package.getResourceString("invisible.type"), new Object[] { foundClassType })) { source = source, position = before };
                    }
                    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 };
                            }
                            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:
                        {
                            foundClassType.makeCompilable();
                            code.createAndAppendNode(parent).setData(before, fldTypeClass, LOAD_CONST, fldConstantFactory.createClass(foundClassType));
                            break label0;
                        }
                        case L_NAME:
                        {
                            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, foundClassType);
                            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)
                {
                    Package foundPackage = (Package) foundItem;
                    if(!foundPackage.isVisibleFrom(enclosingClassType))
                    {
                        throw new TextSourceException(String.format(package.getResourceString("invisible.package"), new Object[] { foundPackage })) { source = source, position = before };
                    }
                    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(foundPackage));
                    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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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.assignment"), 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) break;
                                    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.assignment"), 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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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];
            ClassType typeString = fldTypeString;
            do
            {
                int before = position;
                position = parseMultiplicative(parent, source, position + 1, isStaticOnly);
                Node child2 = parent[-1];
                Type argument1Type = child1.type;
                Type argument2Type = child2.type;
                label0:
                {
                    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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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(operand1 + operand2));
                            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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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.equals(operand2) : !operand1.equals(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)).
                                            append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(operation)).append(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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(O_BIT_AND)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(R_BIT_AND)).append(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)).
                                        append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(O_BIT_XOR)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(R_BIT_XOR)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(O_BIT_OR)).append(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)).append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(R_BIT_OR)).append(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.operand1;
                        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) break;
                        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)).
                                    append(dereferenceClassType).append("." + VIEWNAME_OPERATOR).append(Operator.kindToSymbol(WRITE_COMPONENT)).append(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.assignment"), 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) break;
                            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.assignment"), 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;
                            }
                        }
                    }
                    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 {
        Code code = parent.parentCode;
        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)
                {
                    ClassType enclosingClassType = code.parentCallable.parentType;
                    ImmediateBuilderItemHolder localTypeHolder = getItemHolder();
                    int after = isName ? (
                        tryParseName(parent, source, position, source.getLexemeString(position), localTypeHolder)
                    ) : (
                        tryParseTypeName(source, position, enclosingClassType, localTypeHolder)
                    );
                    Type localType = localTypeHolder.resultType;
                    if(localType != null && source.getLexemeKind(after) == L_NAME)
                    {
                        if(!localType.isVisibleFrom(enclosingClassType))
                        {
                            throw new TextSourceException(String.format(package.getResourceString("invisible.type"), new Object[] { localType })) { source = source, position = position };
                        }
                        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++;
                        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);
            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 {
        Code code = parent.parentCode;
        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)
                {
                    ClassType enclosingClassType = code.parentCallable.parentType;
                    ImmediateBuilderItemHolder localTypeHolder = getItemHolder();
                    int after = isName ? (
                        tryParseName(parent, source, position, source.getLexemeString(position), localTypeHolder)
                    ) : (
                        tryParseTypeName(source, position, enclosingClassType, localTypeHolder)
                    );
                    Type localType = localTypeHolder.resultType;
                    if(localType != null && source.getLexemeKind(after) == L_NAME)
                    {
                        if(!localType.isVisibleFrom(enclosingClassType))
                        {
                            throw new TextSourceException(String.format(package.getResourceString("invisible.type"), new Object[] { localType })) { source = source, position = position };
                        }
                        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 };
                        }
                        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 };
                }
            }
            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.isAssignableFrom(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)).append(name);
            while(source.getLexemeKind(position) == PERIOD && source.getLexemeKind(position + 1) == L_NAME)
            {
                position++;
                if((result = getPackage(specialCanonicalName.append('.').append(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)).append(name);
            while(source.getLexemeKind(position) == PERIOD)
            {
                if(source.getLexemeKind(++position) != L_NAME)
                {
                    result = null;
                    break label0;
                }
                if((result = getClassType(specialCanonicalName.append('.').append(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 mlength = enclosing.length;
        for(ImmediateBuilder parent = fldParent, int mindex = 0; mindex < mlength; mindex++)
        {
            Member member = enclosing[mindex];
            if(member instanceof Callable) parent.parseCallableBody((Callable) member);
        }
        for(Object[] buffer = new Object[mlength], int mindex = 0; mindex < mlength; mindex++)
        {
            Member member = enclosing[mindex];
            if(member instanceof InstInit) for(InstInit thisConstructor = (InstInit) member, int blength = 1, buffer[0] = member; ; )
            {
                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(Array.indexOf(callable, buffer, 0, blength) >= 0)
                {
                    throw new TextSourceException(String.format(
                        package.getResourceString("constructor.recursive-invocation"), new Object[] { callable }
                    )) { source = (TextSource) enclosing.source, position = constructor.position };
                }
                buffer[blength++] = 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 }
}