docs: @Override
      public Object saveView(FacesContext facesContext)
      {
          UIViewRoot uiViewRoot = facesContext.getViewRoot();
          
          if (uiViewRoot.isTransient())
          {
              return null;
          }
          
          Object serializedView = null;
          ResponseStateManager responseStateManager = facesContext.getRenderKit().getResponseStateManager();
          
          String viewId = uiViewRoot.getViewId();
          ViewDeclarationLanguage vdl = facesContext.getApplication().
              getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
          
          try
          {
              facesContext.getAttributes().put(StateManager.IS_SAVING_STATE, Boolean.TRUE);
              if (vdl != null)
              {
                  StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, viewId);
                  
                  if (sms != null)
                  {
                      if (log.isLoggable(Level.FINEST))
                      {
                          log.finest("Calling saveView of StateManagementStrategy: " + sms.getClass().getName());
                      }
                      
                      serializedView = sms.saveView(facesContext);
                      
                      // If MyfacesResponseStateManager is used, give the option to do
                      // additional operations for save the state if is necessary.
                      if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
                      {
                          StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).
                                  saveState(facesContext, serializedView);
                      }
                      
                      return serializedView; 
                  }
              }
      
              // In StateManagementStrategy.saveView there is a check for transient at
              // start, but the same applies for VDL without StateManagementStrategy,
              // so this should be checked before call parent (note that parent method
              // does not do this check).
              if (uiViewRoot.isTransient())
              {
                  return null;
              }
      
              if (log.isLoggable(Level.FINEST))
              {
                  log.finest("Entering saveSerializedView");
              }
      
              checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet<String>());
      
              if (log.isLoggable(Level.FINEST))
              {
                  log.finest("Processing saveSerializedView - Checked for duplicate Ids");
              }
      
              // SerializedView already created before within this request?
              serializedView = facesContext.getAttributes().get(SERIALIZED_VIEW_REQUEST_ATTR);
              if (serializedView == null)
              {
                  if (log.isLoggable(Level.FINEST))
                  {
                      log.finest("Processing saveSerializedView - create new serialized view");
                  }
      
                  // first call to saveSerializedView --> create SerializedView
                  Object treeStruct = getTreeStructureToSave(facesContext);
                  Object compStates = getComponentStateToSave(facesContext);
                  Object rlcStates = !facesContext.getResourceLibraryContracts().isEmpty() ? 
                      UIComponentBase.saveAttachedState(facesContext, 
                                  new ArrayList<String>(facesContext.getResourceLibraryContracts())) : null;
                  serializedView = new Object[] {
                          new Object[]{treeStruct, rlcStates} ,
                          compStates};
                  facesContext.getAttributes().put(SERIALIZED_VIEW_REQUEST_ATTR,
                                                      serializedView);
      
                  if (log.isLoggable(Level.FINEST))
                  {
                      log.finest("Processing saveSerializedView - new serialized view created");
                  }
              }
              
              // If MyfacesResponseStateManager is used, give the option to do
              // additional operations for save the state if is necessary.
              if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
              {
                  StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).
                          saveState(facesContext, serializedView);
              }
      
              if (log.isLoggable(Level.FINEST))
              {
                  log.finest("Exiting saveView");
              }
          }
          finally
          {
              facesContext.getAttributes().remove(StateManager.IS_SAVING_STATE);
          }
  
          return serializedView;
      }