/**
  * * Transforms a given ScalarConstantPtg to its correspondent in the internal model.
  *
  * @param scalar The given ScalarConstantPtg.
  * @return The correspondent of the given ScalarConstantPtg in the internal model.
  */
 private ScalarConstant transform(ScalarConstantPtg scalar) {
   ScalarConstant constant = new ScalarConstant();
   // Transform to Integer.
   if (scalar instanceof IntPtg) {
     constant.setIntegerValue(((IntPtg) scalar).getValue());
   }
   // Transform to Double.
   if (scalar instanceof NumberPtg) {
     constant.setNumericValue(((NumberPtg) scalar).getValue());
   }
   // Transform to String.
   if (scalar instanceof StringPtg) {
     constant.setTextValue(((StringPtg) scalar).getValue());
   }
   // Transform to Boolean.
   if (scalar instanceof BoolPtg) {
     constant.setBooleanValue(((BoolPtg) scalar).getValue());
   }
   // Transform to Error.
   if (scalar instanceof ErrPtg) {
     constant.setErrorValue(ErrorEval.getText(((ErrPtg) scalar).getErrorCode()));
   }
   if (scalar instanceof MissingArgPtg) {
     // TODO: Implement.
   }
   return constant;
 }
  /**
   * * Pops the given number of elements from the given stack of ptgs, transforms them to {@link
   * ITokenElement}s and adds them to the given token container. Ptgs whose transformation is not
   * supported yet, will be added as an {@link UnsupportedToken};
   *
   * @param ptgs The given stack of Ptgs.
   * @param tokenContainer The given token container to add the tokens to.
   * @param ptgsToTransform The number of Ptgs the method is allowed to transform.
   */
  private void transform(
      Cell cell, Stack<Ptg> ptgs, ITokenContainer tokenContainer, Integer ptgsToTransform) {
    Integer transformedPtgs = 0;
    // Loop until stack is empty or number of ptgsToTransform is reached.
    while (!ptgs.isEmpty() & transformedPtgs < ptgsToTransform) {

      // Pop the Ptg that is to be tansformed.
      Ptg ptg = ptgs.pop();
      transformedPtgs++;

      ITokenElement transformedToken = new UnsupportedToken();

      // Transform an ArrayPtg.
      if (ptg instanceof ArrayPtg) {
        // TODO: Implement Array Formulas
      }

      // Transform a ControlPtg.
      if (ptg instanceof ControlPtg) {
        if (ptg instanceof AttrPtg) {
          AttrPtg aptg = (AttrPtg) ptg;
          // TODO: AttrPtg seems to be some junk record with different
          // functionality. Not all applications of AttrPtg have been
          // implemented
          // yet.

          if (aptg.isOptimizedChoose() || aptg.isSum() || aptg.isOptimizedIf()) {
            // Create function.
            Function function = new Function();
            function.setContainer(tokenContainer);
            function.setName(aptg.toFormulaString());

            // Set function as transformed token.
            transformedToken = function;

            // Transform the arguments of the current function and
            // add them to the function.
            for (int i = 0; i < aptg.getNumberOfOperands(); i++) {
              // Transform operand tokens.
              transform(cell, ptgs, function, 1);
            }
          }
        } else if (ptg instanceof ParenthesisPtg) {
          // Parenthesis are ignored and thus do not count as a
          // transformed token.
          transformedToken = null;
          transformedPtgs = transformedPtgs - 1;
        }
      }

      // Transform an OperandPtg
      if (ptg instanceof OperandPtg) {
        AbstractReference reference = transform(cell, (OperandPtg) ptg);
        if (reference != null) {
          reference.setContainer(tokenContainer);
          transformedToken = reference;
        }
      }

      // Transform a OperationPtg
      if (ptg instanceof OperationPtg) {
        if (ptg instanceof AbstractFunctionPtg) {
          AbstractFunctionPtg aFuncPtg = (AbstractFunctionPtg) ptg;
          // Create function.
          Function function = new Function();
          function.setContainer(tokenContainer);
          function.setName(aFuncPtg.getName());
          // Set function as transformed token.
          transformedToken = function;

          // Transform the operands of the current function and add
          // them to the function.
          for (int i = 0; i < aFuncPtg.getNumberOfOperands(); i++) {
            // Transform operand tokens.
            transform(cell, ptgs, function, 1);
          }
        }
        if (ptg instanceof ValueOperatorPtg) {
          ValueOperatorPtg voptg = (ValueOperatorPtg) ptg;

          Operator operator = transform(voptg);
          operator.setContainer(tokenContainer);
          // Set function as transformed token.
          transformedToken = operator;

          // Transform the operands of the current operator and add
          // them to the operator.
          for (int i = 0; i < voptg.getNumberOfOperands(); i++) {
            // Transform operand tokens.
            transform(cell, ptgs, operator, 1);
          }
        }
      }

      // Transform a ScalarConstantptg
      if (ptg instanceof ScalarConstantPtg) {
        //
        ScalarConstant constant = transform((ScalarConstantPtg) ptg);
        constant.setContainer(tokenContainer);
        transformedToken = constant;
      }

      // Transform an UnknownPtg
      if (ptg instanceof UnknownPtg) {
        // TODO:Implement
      }

      if (transformedToken != null) {
        // Add transformed token to container.
        tokenContainer.add(transformedToken);
      }
    }
  }