gt:                     if (simulatedStack.size() < 2) return;
context: /*
   * Copyright 2008-2010 Sun Microsystems, Inc.  All Rights Reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Sun designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Sun in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   * CA 95054 USA or visit www.sun.com if you need additional information or
   * have any questions.
   */
  
  package com.sun.btrace.compiler;
  
  import com.sun.btrace.org.objectweb.asm.AnnotationVisitor;
  import com.sun.btrace.org.objectweb.asm.Attribute;
  import com.sun.btrace.org.objectweb.asm.ClassVisitor;
  import com.sun.btrace.org.objectweb.asm.FieldVisitor;
  import com.sun.btrace.org.objectweb.asm.Label;
  import com.sun.btrace.org.objectweb.asm.MethodVisitor;
  import com.sun.btrace.org.objectweb.asm.Opcodes;
  import com.sun.btrace.org.objectweb.asm.Type;
  import java.util.ArrayDeque;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Deque;
  import java.util.Iterator;
  import java.util.List;
  
  /**
   *
   * @author Jaroslav Bachorik
   */
  public class Postprocessor extends ClassVisitor {
      private List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>();
      private boolean shortSyntax = false;
      private String className = "";
  
      public Postprocessor(ClassVisitor cv) {
          super(Opcodes.ASM4, cv);
      }
  
      @Override
      public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
          if (((access & Opcodes.ACC_PUBLIC) |
              (access & Opcodes.ACC_PROTECTED) |
              (access & Opcodes.ACC_PRIVATE)) == 0)
          {
              shortSyntax = true; // specifying "class <MyClass>" rather than "public class <MyClass>" means using short syntax
              access |= Opcodes.ACC_PUBLIC; // force the public modifier on the btrace class
          }
          className = name;
          super.visit(version, access, name, signature, superName, interfaces);
      }
  
      @Override
      public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
          if (!shortSyntax) return super.visitMethod(access, name, desc, signature, exceptions);
  
          if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE)) == 0) {
              access &= ~Opcodes.ACC_PROTECTED;
              access |= Opcodes.ACC_PUBLIC;
          }
          final int localVarOffset = ((access & Opcodes.ACC_STATIC) == 0) ? -1 : 0;
          access |= Opcodes.ACC_STATIC;
  
          boolean isconstructor = false;
          if ("<init>".equals(name)) {
              name = "<clinit>";
              isconstructor = true;
          }
  
          MethodVisitor mv = new MethodConvertor(localVarOffset, isconstructor, super.visitMethod(access, name, desc, signature, exceptions));
          return mv;
      }
  
      @Override
      public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
          if (!shortSyntax) return super.visitField(access, name, desc, signature, value);
          
          final List<Attribute> attrs = new ArrayList<Attribute>();
          return new FieldVisitor(Opcodes.ASM4) {
  
              public AnnotationVisitor visitAnnotation(String string, boolean bln) {
                  return new AnnotationVisitor(Opcodes.ASM4){
                  };
              }
  
              public void visitAttribute(Attribute atrbt) {
                  attrs.add(atrbt);
  
              }
  
              public void visitEnd() {
                  FieldDescriptor fd = new FieldDescriptor(access, name, desc,
                      signature, value, attrs);
                  fields.add(fd);
              }
          };
      }
  
      @Override
      public void visitEnd() {
          if (shortSyntax) {
              addFields();
          }
      }
  
      private void addFields() {
          for (FieldDescriptor fd : fields) {
              String fieldName = fd.name;
              int fieldAccess = fd.access;
              String fieldDesc = fd.desc;
              String fieldSignature = fd.signature;
              Object fieldValue = fd.value;
  
              fieldAccess &= ~Opcodes.ACC_PRIVATE;
              fieldAccess &= ~Opcodes.ACC_PROTECTED;
              fieldAccess |= Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
  
              FieldVisitor fv = super.visitField(fieldAccess,
                                   fieldName,
                                   fieldDesc, fieldSignature, fieldValue);
  
              for (Attribute attr : fd.attributes) {
                  fv.visitAttribute(attr);
              }
              fv.visitEnd();
          }
      }
  
      private class MethodConvertor extends MethodVisitor {
          private Deque<Boolean> simulatedStack = new ArrayDeque<Boolean>();
          private int localVarOffset = 0;
          private boolean isConstructor;
          private boolean copyEnabled = false;
  
          public MethodConvertor(int localVarOffset, boolean isConstructor, MethodVisitor mv) {
              super(Opcodes.ASM4, mv);
              this.localVarOffset = localVarOffset;
              this.isConstructor = isConstructor;
              this.copyEnabled = !isConstructor; // copy is enabled by default for all methods except constructor
          }
  
          @Override
          public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
              if (index + localVarOffset < 0 || !copyEnabled) {
                  return;
              }
              super.visitLocalVariable(name, desc, signature, start, end, index + localVarOffset);
          }
  
          @Override
          public void visitVarInsn(int opcode, int var) {
              boolean delegate = true;
              switch (opcode) {
                  case Opcodes.ALOAD: {
                      delegate = (var + localVarOffset) >= 0;
                      simulatedStack.push(!delegate);
                      break;
                  }
                  case Opcodes.LLOAD:
                  case Opcodes.DLOAD: {
                      simulatedStack.push(Boolean.FALSE);
                      // long and double occoupy 2 stack slots; fall through
                  }
                  case Opcodes.ILOAD:
                  case Opcodes.FLOAD:
                  {
                      simulatedStack.push(Boolean.FALSE);
                      break;
                  }
                  case Opcodes.LSTORE:
                  case Opcodes.DSTORE: {
                      simulatedStack.poll();
                      // long and double occoupy 2 stack slots; fall through
                  }
                  case Opcodes.ASTORE:
                  case Opcodes.ISTORE:
                  case Opcodes.FSTORE: {
                      simulatedStack.poll();
                      break;
                  }
              }
  
              if (delegate && copyEnabled) super.visitVarInsn(opcode, var + localVarOffset);
          }
  
          @Override
          public void visitInsn(int opcode) {
              switch(opcode) {
                  case Opcodes.POP: {
                      if (simulatedStack.pop()) {
                          return;
                      }
                      break;
                  }
                  case Opcodes.POP2: {
                      Boolean[] vals = new Boolean[2];
                      vals[0] = simulatedStack.poll();
                      vals[1] = simulatedStack.poll();
                      if (vals[0] && vals[1]) {
                          return;
                      } else if (vals[0] || vals[1]) {
                          opcode = Opcodes.POP;
                      }
                      break;
                  }
                  case Opcodes.DUP: {
                      Boolean val = simulatedStack.peek();
                      val = val != null ? val : Boolean.FALSE;
                      simulatedStack.push(val);
                      if (val) return;
                      break;
                  }
                  case Opcodes.DUP_X1: {
  