@Override
  public PartIteration filterPartIteration(PartMaster partMaster) {

    if (type.equals(ProductBaseline.BaselineType.RELEASED)) {

      for (PartIteration pi : partIterations) {
        if (pi.getPartRevision().getPartMaster().getKey().equals(partMaster.getKey())) {
          retainedPartIterations.add(pi);
          return pi;
        }
      }
      // Else, take the latest released
      PartRevision lastReleasedRevision = partMaster.getLastReleasedRevision();
      if (lastReleasedRevision != null) {
        PartIteration pi = lastReleasedRevision.getLastIteration();
        retainedPartIterations.add(pi);
        return pi;
      }

    } else if (type.equals(ProductBaseline.BaselineType.LATEST)) {

      PartIteration pi = partMaster.getLastRevision().getLastCheckedInIteration();

      if (pi != null) {
        retainedPartIterations.add(pi);
        return pi;
      }
    }

    return null;
  }
  public static void generateInstanceStreamWithGlobalMatrix(
      IProductManagerLocal productService,
      List<PartLink> currentPath,
      Matrix4d matrix,
      VirtualInstanceCollection virtualInstanceCollection,
      List<Integer> instanceIds,
      JsonGenerator jg) {
    try {

      PartLink partLink = currentPath.get(currentPath.size() - 1);
      PSFilter filter = virtualInstanceCollection.getFilter();
      List<PartIteration> filteredPartIterations = filter.filter(partLink.getComponent());

      if (!filteredPartIterations.isEmpty()) {

        PartIteration partI = filteredPartIterations.iterator().next();

        // Filter ACL on part
        if (!productService.canAccess(partI.getPartRevision().getKey())) {
          return;
        }

        for (CADInstance instance : partLink.getCadInstances()) {

          List<Integer> copyInstanceIds = new ArrayList<>(instanceIds);
          copyInstanceIds.add(instance.getId());

          Vector3d instanceTranslation =
              new Vector3d(instance.getTx(), instance.getTy(), instance.getTz());
          Vector3d instanceRotation =
              new Vector3d(instance.getRx(), instance.getRy(), instance.getRz());
          Matrix4d combinedMatrix =
              combineTransformation(matrix, instanceTranslation, instanceRotation);

          if (!partI.isAssembly() && !partI.getGeometries().isEmpty()) {
            writeLeaf(currentPath, copyInstanceIds, partI, combinedMatrix, jg);
          } else {
            for (PartLink subLink : partI.getComponents()) {
              List<PartLink> subPath = new ArrayList<>(currentPath);
              subPath.add(subLink);
              generateInstanceStreamWithGlobalMatrix(
                  productService,
                  subPath,
                  combinedMatrix,
                  virtualInstanceCollection,
                  copyInstanceIds,
                  jg);
            }
          }
        }
      }

    } catch (UserNotFoundException
        | UserNotActiveException
        | WorkspaceNotFoundException
        | PartRevisionNotFoundException e) {
      e.printStackTrace();
    }
  }
  public static void generateInstanceStreamWithGlobalMatrix(
      IProductManagerLocal productService,
      List<PartLink> currentPath,
      Matrix4d matrix,
      InstanceCollection instanceCollection,
      List<Integer> instanceIds,
      JsonGenerator jg) {

    try {

      if (currentPath == null) {
        PartLink rootPartUsageLink =
            productService.getRootPartUsageLink(instanceCollection.getCiKey());
        currentPath = new ArrayList<>();
        currentPath.add(rootPartUsageLink);
      }

      Component component =
          productService.filterProductStructure(
              instanceCollection.getCiKey(), instanceCollection.getFilter(), currentPath, 1);

      PartLink partLink = component.getPartLink();
      PartIteration partI = component.getRetainedIteration();

      // Filter ACL on part
      if (!productService.canAccess(partI.getPartRevision().getKey())) {
        return;
      }

      for (CADInstance instance : partLink.getCadInstances()) {

        List<Integer> copyInstanceIds = new ArrayList<>(instanceIds);
        copyInstanceIds.add(instance.getId());

        Vector3d instanceTranslation =
            new Vector3d(instance.getTx(), instance.getTy(), instance.getTz());
        Vector3d instanceRotation =
            new Vector3d(instance.getRx(), instance.getRy(), instance.getRz());
        Matrix4d combinedMatrix =
            combineTransformation(matrix, instanceTranslation, instanceRotation);

        if (!partI.isAssembly()
            && !partI.getGeometries().isEmpty()
            && instanceCollection.isFiltered(currentPath)) {
          writeLeaf(currentPath, copyInstanceIds, partI, combinedMatrix, jg);
        } else {
          for (Component subComponent : component.getComponents()) {
            generateInstanceStreamWithGlobalMatrix(
                productService,
                subComponent.getPath(),
                combinedMatrix,
                instanceCollection,
                copyInstanceIds,
                jg);
          }
        }
      }

    } catch (PartMasterNotFoundException
        | PartRevisionNotFoundException
        | PartUsageLinkNotFoundException
        | UserNotFoundException
        | WorkspaceNotFoundException
        | ConfigurationItemNotFoundException e) {
      LOGGER.log(Level.SEVERE, null, e);
    } catch (AccessRightException
        | EntityConstraintException
        | NotAllowedException
        | UserNotActiveException e) {
      LOGGER.log(Level.FINEST, null, e);
    }
  }