/** {@inheritDoc} */
 public VoProductType getById(final long id) throws Exception {
   final ProductTypeDTO typeDTO = dtoProductTypeService.getById(id);
   if (typeDTO != null /* && federationFacade.isCurrentUserSystemAdmin() */) {
     final VoProductType type =
         voAssemblySupport.assembleVo(
             VoProductType.class, ProductTypeDTO.class, new VoProductType(), typeDTO);
     final List<ProdTypeAttributeViewGroupDTO> groups =
         dtoProdTypeAttributeViewGroupService.getByProductTypeId(id);
     final List<VoProductTypeViewGroup> voGroups =
         voAssemblySupport.assembleVos(
             VoProductTypeViewGroup.class, ProdTypeAttributeViewGroupDTO.class, groups);
     type.setViewGroups(voGroups);
     return type;
   } else {
     throw new AccessDeniedException("Access is denied");
   }
 }
  /** {@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());
  }