docs: private void _createFieldDebugInfo(FacesContext facesContext,
              final String field, Object oldValue, 
              Object newValue, final int skipStackTaceElements)
      {
          if (oldValue == null && newValue == null)
          {
              // both values are null, not interesting and can
              // happen a lot in UIData with saving and restoring state
              return;
          }
          
          if (facesContext.getViewRoot() == null)
          {
              // No viewRoot set, it is creating component, 
              // so it is not possible to calculate the clientId, 
              // abort processing because the interesting part will
              // happen later.
              return;
          }
          
          if (getParent() == null || !isInView())
          {
              //Skip if no parent or is not in view
              return;
          }
          
          // convert Array values into a more readable format
          if (oldValue != null && oldValue.getClass().isArray() && Object[].class.isAssignableFrom(oldValue.getClass()))
          {
              oldValue = Arrays.deepToString((Object[]) oldValue);
          }
          if (newValue != null && newValue.getClass().isArray() && Object[].class.isAssignableFrom(newValue.getClass()))
          {
              newValue = Arrays.deepToString((Object[]) newValue);
          }
          
          // use Throwable to get the current call stack
          Throwable throwableHelper = new Throwable();
          StackTraceElement[] stackTraceElements = throwableHelper.getStackTrace();
          List<StackTraceElement> debugStackTraceElements = new LinkedList<StackTraceElement>();
          
          // + 1 because this method should also be skipped
          for (int i = skipStackTaceElements + 1; i < stackTraceElements.length; i++)
          {
              debugStackTraceElements.add(stackTraceElements[i]);
              
              if (FacesServlet.class.getCanonicalName()
                      .equals(stackTraceElements[i].getClassName()))
              {
                  // stop after the FacesServlet
                  break;
              }
          }
          
          // create the debug-info array
          // structure:
          //     - 0: phase
          //     - 1: old value
          //     - 2: new value
          //     - 3: StackTraceElement List
          // NOTE that we cannot create a class here to encapsulate this data,
          // because this is not on the spec and the class would not be available in impl.
          Object[] debugInfo = new Object[4];
          debugInfo[0] = facesContext.getCurrentPhaseId();
          debugInfo[1] = oldValue;
          debugInfo[2] = newValue;
          debugInfo[3] = debugStackTraceElements;
          
          // add the debug info
          _getFieldDebugInfos(field).add(debugInfo);
      }