class CaseManagementSwitchViewServiceImpl implements CaseManagementSwitchViewService {

    @Override
    @SuppressWarnings("unchecked")
    public Optional<ProjectDiagram> switchView(final Diagram diagram, final String mappedDefSetId, final String mappedShapeSetId) {
        final Metadata metadata = diagram.getMetadata();
        final String defSetId = metadata.getDefinitionSetId();

        final Optional<DefinitionSetService> definitionSetServiceOptional =
                definitionSetServices.stream().filter(s -> s.accepts(defSetId)).findAny();

        return definitionSetServiceOptional.map(service -> {
            try {
                // Marshall the diagram
                final String rawData = service.getDiagramMarshaller().marshall(diagram);

                // Get the mapped unmarshaller
                final Optional<DefinitionSetService> mappedDefinitionSetServiceOptional = definitionSetServices.stream()
                        .filter(s -> s.accepts(mappedDefSetId)).findAny();

                return mappedDefinitionSetServiceOptional.map(mappedService -> {
                    ((AbstractMetadata) metadata).setDefinitionSetId(mappedDefSetId);

                    // Unmarshall the diagram
                    try (final InputStream inputStream = new ByteArrayInputStream(rawData.getBytes())) {
                        final Graph<DefinitionSet, Node> graph = mappedService.getDiagramMarshaller().unmarshall(metadata, inputStream);

                        final DiagramFactory factory = factoryManager.registry().getDiagramFactory(graph.getContent().getDefinition(),
                                                                                                   metadata.getMetadataType());
                        final ProjectDiagram mappedDiagram = (ProjectDiagram) factory.build(metadata.getTitle(), metadata, graph);

                        mappedDiagram.getMetadata().setShapeSetId(mappedShapeSetId);

                        return mappedDiagram;
                    } catch (IOException e) {
                        return CaseManagementSwitchViewServiceImpl.this.handleError(Optional.of(e));
                    }
                }).orElseGet(() -> CaseManagementSwitchViewServiceImpl.this.handleError(Optional.empty()));
            } catch (IOException e) {
                return CaseManagementSwitchViewServiceImpl.this.handleError(Optional.of(e));
            }
        });
    }

    @Inject public  CaseManagementSwitchViewServiceImpl(final FactoryManager factoryManager,
                                               final Instance<DefinitionSetService> definitionSetServiceInstances);

}