public Object visit(SpreadExpression node) {
            // generate expression
            Expression expr = node.getExpression();
            generate(expr);

            // store local variable
            LocalVariable collection =
                mBuilder.createLocalVariable(null, makeDesc(expr.getType()));
            mBuilder.storeLocal(collection);

            // get associated type
            Class<?> exprClass = expr.getType().getNaturalClass();

            // get associated element type
            Type elementType = null;
            try { elementType = expr.getType().getIterationElementType(); }
            catch (IntrospectionException exception) {
                throw new IllegalStateException(exception);
            }

            Class<?> elementClass = elementType.getNaturalClass();

            // handle null values and return null
            mBuilder.loadLocal(collection);
            Label endLabel = mBuilder.createLabel();
            Label nullLabel = mBuilder.createLabel();
            mBuilder.ifNullBranch(nullLabel, true);

            // handle collections
            if (Collection.class.isAssignableFrom(exprClass)) {

                // create new collection
                TypeDesc arrayList = makeDesc(node.getType());
                mBuilder.newObject(arrayList);
                mBuilder.dup();

                // get length of collection
                mBuilder.loadLocal(collection);
                mBuilder.invoke(getMethod(Collection.class, "size"));

                // instantiate based on length of collection
                mBuilder.invokeConstructor(node.getType().getClassName(),
                                           makeDesc(int.class));

                // store instance
                LocalVariable list =
                    mBuilder.createLocalVariable(null, arrayList);
                mBuilder.storeLocal(list);

                // generate collection iterator
                mBuilder.loadLocal(collection);
                LocalVariable iterator =
                    mBuilder.createLocalVariable(null, makeDesc(Iterator.class));

                mBuilder.invoke(getMethod(Collection.class, "iterator"));
                mBuilder.storeLocal(iterator);

                // generate labels for checking foreach condition
                Label endLoopLabel = mBuilder.createLabel();
                Label checkLabel = mBuilder.createLabel();
                mBuilder.branch(checkLabel);

                // start foreach loop
                Label startLabel = mBuilder.createLabel().setLocation();
                Label continueLabel = mBuilder.createLabel();

                // load list for invoking add on
                mBuilder.loadLocal(list);

                // get the loop variable
                mBuilder.loadLocal(iterator);
                mBuilder.invokeInterface("java.util.Iterator", "next",
                                         TypeDesc.OBJECT);

                // avoid null types
                mBuilder.dup();
                Label addLabel = mBuilder.createLabel();
                mBuilder.ifNullBranch(addLabel, true);

                // verify cast
                if (elementClass != Object.class) {
                    mBuilder.checkCast(makeDesc(elementClass));
                }

                // generate underlying expression
                generate(node.getOperation());

                // add to list
                addLabel.setLocation();
                mBuilder.invoke(getMethod(List.class, "add", Object.class));
                mBuilder.ifZeroComparisonBranch(nullLabel, "==");

                // set entry point for continue
                continueLabel.setLocation();
                checkLabel.setLocation();

                // determine if has next
                mBuilder.loadLocal(iterator);
                mBuilder.invokeInterface("java.util.Iterator", "hasNext",
                                         TypeDesc.BOOLEAN);

                mBuilder.ifZeroComparisonBranch(startLabel, "!=");

                endLoopLabel.setLocation();

                // load list as the result
                mBuilder.loadLocal(list);
            }

            // handle arrays
            else if (exprClass.isArray()) {

                // create new array
                Type operationType = node.getOperation().getType();
                TypeDesc arrayType = makeDesc(node.getType());

                // calculate length of array
                LocalVariable length =
                    mBuilder.createLocalVariable(null, TypeDesc.INT);
                mBuilder.loadLocal(collection);
                mBuilder.arrayLength();
                mBuilder.storeLocal(length);

                // get length of array
                mBuilder.loadLocal(length);
                mBuilder.newObject(arrayType);

                // store instance
                LocalVariable array =
                    mBuilder.createLocalVariable(null, arrayType);
                mBuilder.storeLocal(array);

                // create end label
                Label endLoopLabel = mBuilder.createLabel();

                // setup start value
                LocalVariable indexLocal =
                    mBuilder.createLocalVariable(null, TypeDesc.INT);
                mBuilder.loadConstant(0);
                mBuilder.storeLocal(indexLocal);

                // perform initial loop check
                Label checkLabel = mBuilder.createLabel();
                mBuilder.branch(checkLabel);

                // start loop body
                Label startLabel = mBuilder.createLabel().setLocation();
                Label continueLabel = mBuilder.createLabel();

                // load array for adding
                mBuilder.loadLocal(array);
                mBuilder.loadLocal(indexLocal);

                // load array value
                mBuilder.loadLocal(collection);
                mBuilder.loadLocal(indexLocal);
                mBuilder.loadFromArray(TypeDesc.OBJECT);

                // avoid null types
                mBuilder.dup();
                Label addLabel = mBuilder.createLabel();
                Label null2Label = mBuilder.createLabel();
                mBuilder.ifNullBranch(null2Label, true);

                // generate underlying expression
                generate(node.getOperation());
                mBuilder.branch(addLabel);

                // handle null default values
                null2Label.setLocation();
                mBuilder.pop();
                if (operationType.isPrimitive()) {
                    Class<?> clazz = operationType.getNaturalClass();
                    if (int.class.equals(clazz)) {
                        mBuilder.loadConstant(0);
                    }
                    else if (boolean.class.equals(clazz)) {
                        mBuilder.loadConstant(false);
                    }
                    else if (double.class.equals(clazz)) {
                        mBuilder.loadConstant(0.0);
                    }
                    else if (float.class.equals(clazz)) {
                        mBuilder.loadConstant(0.0f);
                    }
                    else if (long.class.equals(clazz)) {
                        mBuilder.loadConstant(0L);
                    }
                    else { mBuilder.loadConstant(0); }
                }
                else { mBuilder.loadNull(); }

                // store to array
                addLabel.setLocation();
                mBuilder.storeToArray(makeDesc(operationType));

                // set entry point for continue
                continueLabel.setLocation();

                // build check label location and index adjustment
                mBuilder.integerIncrement(indexLocal, 1);
                checkLabel.setLocation();

                mBuilder.loadLocal(indexLocal);
                mBuilder.loadLocal(length);
                mBuilder.ifComparisonBranch(startLabel, "<");

                endLoopLabel.setLocation();

                // load array as the result
                mBuilder.loadLocal(array);
            }

            // skip past null check to end
            mBuilder.branch(endLabel);

            // null handle checking
            nullLabel.setLocation();
            mBuilder.loadNull();

            // finish operation
            endLabel.setLocation();

            return null;
        }