class SparkLibraryHelper extends TypeSwitch {

  private PAG pag;
  private Node node;
  private SootMethod method;

  /**
   * The constructor for this {@link TypeSwitch}.
   *
   * @param pag
   *          the pointer assignment graph in that the new edges and nodes should be added into.
   * @param node
   *          the node of the value for which allocations should be made.
   * @param method
   *          the method in which the allocations should take place. This parameter can be null.
   */
  public SparkLibraryHelper(PAG pag, Node node, SootMethod method) {
    this.pag = pag;
    this.node = node;
    this.method = method;
  }

  /**
   * A new local will be created and connected to {@link SparkLibraryHelper#node} of type {@link RefType}. For this new local
   * an allocation edge to {@link AnySubType} of its declared type will be added.
   */
  @Override
  public void caseRefType(RefType t) {<FILL_FUNCTION_BODY>}

  /**
   * A new local array will be created and connected to {@link SparkLibraryHelper#node} of type {@link ArrayType}. For this
   * new local an allocation edge to a new array of its declared type will be added. If the
   * {@link ArrayType#getElementType()} is still an array an allocation to a new array of this element type will be made and
   * stored until the element type is a {@link RefType}. If this is the case an allocation to {@link AnySubType} of
   * {@link ArrayType#baseType} will be made.
   */
  @Override
  public void caseArrayType(ArrayType type) {
    Node array = node;
    for (Type t = type; t instanceof ArrayType; t = ((ArrayType) t).getElementType()) {
      ArrayType at = (ArrayType) t;
      if (at.baseType instanceof RefType) {

        // var tmpArray;
        LocalVarNode localArray = pag.makeLocalVarNode(new Object(), t, method);

        // x = tmpArray;
        pag.addEdge(localArray, array);

        // new T[]
        AllocNode newArray = pag.makeAllocNode(new Object(), at, method);

        // tmpArray = new T[]
        pag.addEdge(newArray, localArray);

        // tmpArray[i]
        FieldRefNode arrayRef = pag.makeFieldRefNode(localArray, ArrayElement.v());

        // var tmp
        LocalVarNode local = pag.makeLocalVarNode(new Object(), at.getElementType(), method);

        // tmpArray[i] = tmp
        pag.addEdge(local, arrayRef);

        // x = tmp
        array = local;

        if (at.numDimensions == 1) {
          // new T()
          AllocNode alloc = pag.makeAllocNode(new Object(), AnySubType.v((RefType) at.baseType), method);

          // tmp = new T()
          pag.addEdge(alloc, local);
        }
      }
    }
  }

}

    // var tmp;
    VarNode local = pag.makeLocalVarNode(new Object(), t, method);

    // new T();
    AllocNode alloc = pag.makeAllocNode(new Object(), AnySubType.v(t), method);

    // tmp = new T();
    pag.addAllocEdge(alloc, local);

    // x = tmp;
    pag.addEdge(local, node);
  
<methods>public non-sealed void <init>() ,public void caseAnySubType(soot.AnySubType) ,public void caseArrayType(soot.ArrayType) ,public void caseBooleanType(soot.BooleanType) ,public void caseByteType(soot.ByteType) ,public void caseCharType(soot.CharType) ,public void caseDefault(soot.Type) ,public void caseDoubleType(soot.DoubleType) ,public void caseErroneousType(soot.ErroneousType) ,public void caseFloatType(soot.FloatType) ,public void caseIntType(soot.IntType) ,public void caseLongType(soot.LongType) ,public void caseNullType(soot.NullType) ,public void caseRefType(soot.RefType) ,public void caseShortType(soot.ShortType) ,public void caseStmtAddressType(soot.StmtAddressType) ,public void caseUnknownType(soot.UnknownType) ,public void caseVoidType(soot.VoidType) ,public void defaultCase(soot.Type) ,public java.lang.Object getResult() ,public void setResult(java.lang.Object) <variables>java.lang.Object result