(filename))
        with file.open(self.mode, **open_params) as handle:
            self._handle = handle
            yield handle

    def _iter_handles(
        self,
        filenames: Iterable[str],
        template: Union[str, Template],
        template_params: dict,
        open_params: Optional[dict] = None,
    ) -> Iterator[IO[AnyStr]]:
        """Helper method for iteration over generated files. Given additional kwargs
        will be passed to :meth:`Path.open` method.

        Parameters
        ----------
        filenames: list of str
            list of source filenames, used as value for `${conf}` placeholder
            in *name_template*
        template_params : dict
            Dictionary of {identifier: value} for `.make_name` method.
        open_params : dict, optional
            arguments for :meth:`Path.open` used to open file.

        Yields
        ------
        TextIO
            file handle, will be closed automatically on next iteration

        :meta public:
        """
        open_params = open_params or {}  # empty dict by default
        for num, fnm in enumerate(filenames):
            template_params.update({"conf": fnm, "num": num})
            filename = self.make_name(template=template, **template_params)
            file = self.check_file(self.destination.joinpath(filename))
            with file.open(self.mode, **open_params) as handle:
                yield handle

    def _dataarray_handler(self, data: List[DataArray], extras: Dict[str, Any]) -> None:
        self.generic(data)

    def _integerarray_handler(
        self, data: List[IntegerArray], extras: Dict[str, Any]
    ) -> None:
        self.generic(data)

    def _floatarray_handler(
        self, data: List[FloatArray], extras: Dict[str, Any]
    ) -> None:
        self.generic(data)

    def _booleanarray_handler(
        self, data: List[BooleanArray], extras: Dict[str, Any]
    ) -> None:
        self.generic(data)

    def _infoarray_handler(self, data: List[InfoArray], extras: Dict[str, Any]) -> None:
        self.generic(data)

    def _energies_handler(self, data: List[Energies], extras: Dict[str, Any]) -> None:
        self.overview(
            data,
            frequencies=extras.get("frequencies"),
            stoichiometry=extras.get("stoichiometry"),
        )
        for en in data:
            self.energies(
                en, corrections=extras.get("corrections", dict()).get(en.genre)
            )

    def _vibrationalactivities_handler(
        self, data: List[VibrationalActivities], extras: Dict[str, Any]
    ) -> None:
        self.spectral_activities(band=extras["frequencies"], data=data)

    def _scatteringactivities_handler(
        self, data: List[ScatteringActivities], extras: Dict[str, Any]
    ) -> None:
        self.spectral_activities(band=extras["frequencies"], data=data)

    def _electronicactivities_handler(
        self, data: List[ElectronicActivities], extras: Dict[str, Any]
    ) -> None:
        self.spectral_activities(band=extras["wavelengths"], data=data)

    def _vibrationaldata_handler(
        self, data: List[VibrationalData], extras: Dict[str, Any]
    ) -> None:
        self.spectral_data(band=extras["frequencies"], data=data)

    def _scatteringdata_handler(
        self, data: List[ScatteringData], extras: Dict[str, Any]
    ) -> None:
        self.spectral_data(band=extras["frequencies"], data=data)

    def _electronicdata_handler(
        self, data: List[ElectronicData], extras: Dict[str, Any]
    ) -> None:
        self.spectral_data(band=extras["wavelengths"], data=data)

    def _transitions_handler(
        self, data: List[Transitions], extras: Dict[str, Any]
    ) -> None:
        if len(data) > 1:
            raise ValueError(
                "Got multiple *Transitions* objects, but can write contents "
                "of only one such object for.write() call."
            )
        self.transitions(transitions=data[0], wavelengths=extras["wavelengths"])

    def _geometry_handler(self, data: List[Geometry], extras: Dict[str, Any]) -> None:
        if len(data) > 1:
            raise ValueError(
                "Got multiple *Geometry* objects, but can write contents "
                "of only one such object for.write() call."
            )
        self.geometry(
            data[0],
            charge=extras.get("charge"),
            multiplicity=extras.get("multiplicity"),
        )

    def _spectra_handler(self, data: List[Spectra], _extras) -> None:
        for spc in data:
            self.spectra(spc)

    def _singlespectrum_handler(self, data: List[SingleSpectrum], _extras) -> None:
        for spc in data:
            self.single_spectrum(spc)

    def write(self, data: List) -> None:
        """Writes :class:`.DataArray`-like objects to disk, decides how to write them
        based on the type of each object. If some types of given objects are not
        supported by this writer, data of this type is ignored and a warning is emitted.

        Parameters
        ----------
        data : List
            :class:`.DataArray`-like objects that should be written to disk.
        """
        distributed, extras = self.distribute_data(data)
        for name, data_ in distributed.items():
            try:
                handler = getattr(self, f"_{name}_handler")
                handler(data_, extras)
            except (NotImplementedError, AttributeError):
                logger.warning(f"{type(self)} does not handle '{name}' type data.")

    def generic(
        self,
        data: List[_GenericArray],
        name_template: Union[str, Template] = "",
    ):
        """Interface for writing generic data: any that provides one value for each
        conformer. Evoked when handling :class:`.DataArray`, :class:`.IntegerArray`,
        :class:`.FloatArray`, :class:`.BooleanArray`, or :class:`.InfoArray`.

        Parameters
        ----------
        data
            List of objects that provide one value for each conformer.

        Raises
        ------
        NotImplementedError
            Whenever called, this is an interface that should not be used directly.
        """
        raise NotImplementedError(f"Class {type(self)} does not implement this method.")

    def overview(
        self,
        energies: Sequence[Energies],
        frequencies: Optional[Bands] = None,
        stoichiometry: Optional[InfoArray] = None,
        name_template: Union[str, Template] = "",
    ):
        """Intercafe for generating an overview of known conformers: values of energies,
        number of imaginary frequencies, and stoichiometry for each conformer. Evoked
        when handling :class:`.Energies` objects.

        Parameters
        ----------
        energies
            List of objects representing different energies genres for each conformer.
            Mandatory in custom implementation.
        frequencies
            :class:`.Bands` of "freq" genre, with list of frequencies for each
            conformer. Mandatory in custom implementation. May be ``None`` when method
            evoked by handler.
        stoichiometry
            Stoichiometry of each conformer. Mandatory in custom implementation. May be
            ``None`` when method evoked by handler.
        name_template
            Template that defines naming scheme for files generated by this method.
            May be omitted in custom implementation.

        Raises
        ------
        NotImplementedError
            Whenever called, this is an interface that should not be used directly.
        """
        raise NotImplementedError(f"Class {type(self)} does not implement