private void generateNullSafe(Expression node, Expression expr,
                                      NullSafeCallback callback) {
            // TODO: optimize this by skipping all remaining checks if first
            // part of null-safe fails..currently, the way this is written it
            // performs an ifnull check for each section:
            // ie: a?.b?.c?.d will result in 4 ifnull checks even tho if the
            // first fails, all remaining will fail, so we could short circuit

            // define branch labels
            Label endLocation = null;
            Label elseLocation = null;

            // generate branch checks
            if (node instanceof NullSafe) {
                NullSafe nullSafe = (NullSafe) node;
                if (nullSafe.isNullSafe() && expr.getType().isNullable()) {
                    endLocation = mBuilder.createLabel();
                    elseLocation = mBuilder.createLabel();

                    mBuilder.dup();
                    mBuilder.ifNullBranch(elseLocation, true);
                }
            }

            // generate callback
            Type rtype = callback.execute();

            // finish branch checks
            if (node instanceof NullSafe) {
                NullSafe nullSafe = (NullSafe) node;
                if (nullSafe.isNullSafe() && expr.getType().isNullable()) {
                    // if type is primitive, convert
                    //if (type != null && type.isPrimitive()) {
                    //    typeConvertEnd(type, type.toNonPrimitive(), true);
                    //}

                    mBuilder.branch(endLocation);
                    elseLocation.setLocation();

                    Type ntype = rtype == null ? node.getType() : rtype;
                    if (ntype != null && ntype.isPrimitive()) {
                        mBuilder.pop();

                        Class<?> primitive = ntype.getNaturalClass();
                        if (primitive == boolean.class) {
                            mBuilder.loadConstant(false);
                        }
                        else if (primitive == long.class) {
                            mBuilder.loadConstant(0L);
                        }
                        else if (primitive == float.class) {
                            mBuilder.loadConstant(0.0f);
                        }
                        else if (primitive == double.class) {
                            mBuilder.loadConstant(0.0d);
                        }
                        else {
                            mBuilder.loadConstant(0);
                        }
                    }
                    else {
                        mBuilder.checkCast(makeDesc(ntype));
                    }

                    endLocation.setLocation();
                }
            }
        }