/** {@inheritDoc} */
  public VoProductType update(final VoProductType vo) throws Exception {
    final ProductTypeDTO typeDTO = dtoProductTypeService.getById(vo.getProducttypeId());
    if (typeDTO != null && federationFacade.isCurrentUserSystemAdmin()) {
      dtoProductTypeService.update(
          voAssemblySupport.assembleDto(ProductTypeDTO.class, VoProductType.class, typeDTO, vo));

      final List<ProdTypeAttributeViewGroupDTO> groups =
          dtoProdTypeAttributeViewGroupService.getByProductTypeId(vo.getProducttypeId());
      final Map<Long, ProdTypeAttributeViewGroupDTO> existing = new HashMap<>();
      for (final ProdTypeAttributeViewGroupDTO group : groups) {
        existing.put(group.getProdTypeAttributeViewGroupId(), group);
      }

      if (vo.getViewGroups() != null) {
        for (final VoProductTypeViewGroup voGroup : vo.getViewGroups()) {
          final ProdTypeAttributeViewGroupDTO dtoToUpdate =
              existing.get(voGroup.getProdTypeAttributeViewGroupId());
          if (dtoToUpdate != null) {
            // update mode
            existing.remove(dtoToUpdate.getProdTypeAttributeViewGroupId());

            dtoProdTypeAttributeViewGroupService.update(
                voAssemblySupport.assembleDto(
                    ProdTypeAttributeViewGroupDTO.class,
                    VoProductTypeViewGroup.class,
                    dtoToUpdate,
                    voGroup));

          } else {
            // insert mode

            final ProdTypeAttributeViewGroupDTO newGroup =
                dtoProdTypeAttributeViewGroupService.getNew();
            newGroup.setProducttypeId(vo.getProducttypeId());

            dtoProdTypeAttributeViewGroupService.create(
                voAssemblySupport.assembleDto(
                    ProdTypeAttributeViewGroupDTO.class,
                    VoProductTypeViewGroup.class,
                    newGroup,
                    voGroup));
          }
        }
      }

      for (final ProdTypeAttributeViewGroupDTO remove : existing.values()) {
        dtoProdTypeAttributeViewGroupService.remove(remove.getProdTypeAttributeViewGroupId());
      }

    } else {
      throw new AccessDeniedException("Access is denied");
    }
    return getById(vo.getProducttypeId());
  }