gt:             if (nodes[i].block.exits() == 0)
context: /*
   * Javassist, a Java-bytecode translator toolkit.
   * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
   *
   * The contents of this file are subject to the Mozilla Public License Version
   * 1.1 (the "License"); you may not use this file except in compliance with
   * the License.  Alternatively, the contents of this file may be used under
   * the terms of the GNU Lesser General Public License Version 2.1 or later,
   * or the Apache License Version 2.0.
   *
   * Software distributed under the License is distributed on an "AS IS" basis,
   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   * for the specific language governing rights and limitations under the
   * License.
   */
  
  package javassist.bytecode.analysis;
  
  import java.util.ArrayList;
  import javassist.CtClass;
  import javassist.CtMethod;
  import javassist.bytecode.BadBytecode;
  import javassist.bytecode.MethodInfo;
  import javassist.bytecode.stackmap.BasicBlock;
  
  /**
   * Represents the control flow graph of a given method.
   *
   * <p>To obtain the control flow graph, do the following:</p>
   *
   * <pre>CtMethod m = ...
   * ControlFlow cf = new ControlFlow(m);
   * Block[] blocks = cf.basicBlocks();
   * </pre>
   *
   * <p><code>blocks</code> is an array of basic blocks in
   * that method body.</p>
   *
   * @see javassist.CtMethod
   * @see Block
   * @see Frame
   * @see Analyzer
   * @author Shigeru Chiba
   * @since 3.16
   */
  public class ControlFlow {
      private CtClass clazz;
      private MethodInfo methodInfo;
      private Block[] basicBlocks;
      private Frame[] frames;
  
      /**
       * Constructs a control-flow analyzer for the given method.
       */
      public ControlFlow(CtMethod method) throws BadBytecode {
          this(method.getDeclaringClass(), method.getMethodInfo2());
      }
  
      /**
       * Constructs a control-flow analyzer.
       */
      public ControlFlow(CtClass ctclazz, MethodInfo minfo) throws BadBytecode {
          clazz = ctclazz;
          methodInfo = minfo;
          frames = null;
          basicBlocks = (Block[])new BasicBlock.Maker() {
              protected BasicBlock makeBlock(int pos) {
                  return new Block(pos, methodInfo);
              }
              protected BasicBlock[] makeArray(int size) {
                  return new Block[size];
              }
          }.make(minfo);
          int size = basicBlocks.length;
          int[] counters = new int[size];
          for (int i = 0; i < size; i++) {
              Block b = basicBlocks[i];
              b.index = i;
              b.entrances = new Block[b.incomings()];
              counters[i] = 0;
          }
  
          for (int i = 0; i < size; i++) {
              Block b = basicBlocks[i];
              for (int k = 0; k < b.exits(); k++) {
                  Block e = b.exit(k);
                  e.entrances[counters[e.index]++] = b;
              }
          }
      }
  
      /**
       * Returns all the basic blocks in the method body.
       */
      public Block[] basicBlocks() {
          return basicBlocks;
      }
  
      /**
       * Returns the types of the local variables and stack frame entries
       * available at the given position.  If the byte at the position is
       * not the first byte of an instruction, then this method returns
       * null.
       *
       * @param pos       the position.
       */
      public Frame frameAt(int pos) throws BadBytecode {
          if (frames == null)
              frames = new Analyzer().analyze(clazz, methodInfo);
  
          return frames[pos];
      }
  
      /**
       * Constructs a dominator tree.  This method returns an array of
       * the tree nodes.  The first element of the array is the root
       * of the tree.
       * 
       * <p> The order of the elements is the same as that
       * of the elements in the <code>Block</code> array returned
       * by the <code>basicBlocks</code>
       * method.  If a <code>Block</code> object is at the i-th position
       * in the <code>Block</code> array, then  
       * the <code>Node</code> object referring to that
       * <code>Block</code> object is at the i-th position in the
       * array returned by this method.
       * For every array element <code>node</code>, its index in the
       * array is equivalent to <code>node.block().index()</code>. 
       *
       * @return an array of the tree nodes, or null if the method is abstract.
       * @see Node#block()
       * @see Block#index()
       */
      public Node[] dominatorTree() {
          int size = basicBlocks.length;
          if (size == 0)
              return null;
  
          Node[] nodes = new Node[size];
          boolean[] visited = new boolean[size];
          int[] distance = new int[size];
          for (int i = 0; i < size; i++) {
              nodes[i] = new Node(basicBlocks[i]);
              visited[i] = false;
          }
  
          Access access = new Access(nodes) {
              BasicBlock[] exits(Node n) { return n.block.getExit(); }
              BasicBlock[] entrances(Node n) { return n.block.entrances; }
          };
          nodes[0].makeDepth1stTree(null, visited, 0, distance, access);
          for (int i = 0; i < size; i++)
              visited[i] = false;
  
          while (nodes[0].makeDominatorTree(visited, distance, access))
              ;
  
          Node.setChildren(nodes);
          return nodes;
      }
  
      /**
       * Constructs a post dominator tree.  This method returns an array of
       * the tree nodes.  Note that the tree has multiple roots.
       * The parent of the root nodes is null.
       * 
       * <p> The order of the elements is the same as that
       * of the elements in the <code>Block</code> array returned
       * by the <code>basicBlocks</code>
       * method.  If a <code>Block</code> object is at the i-th position
       * in the <code>Block</code> array, then  
       * the <code>Node</code> object referring to that
       * <code>Block</code> object is at the i-th position in the
       * array returned by this method.
       * For every array element <code>node</code>, its index in the
       * array is equivalent to <code>node.block().index()</code>.
       *
       * @return an array of the tree nodes, or null if the method is abstract.
       * @see Node#block()
       * @see Block#index()
       */
      public Node[] postDominatorTree() {
          int size = basicBlocks.length;
          if (size == 0)
              return null;
  
          Node[] nodes = new Node[size];
          boolean[] visited = new boolean[size];
          int[] distance = new int[size];
          for (int i = 0; i < size; i++) {
              nodes[i] = new Node(basicBlocks[i]);
              visited[i] = false;
          }
  
          Access access = new Access(nodes) {
              BasicBlock[] exits(Node n) { return n.block.entrances; }
              BasicBlock[] entrances(Node n) { return n.block.getExit(); }
          };
  
          int counter = 0;
          for (int i = 0; i < size; i++)
  