def build_iterator(self, name, base_dataset_name, batch_size, repeat, shuffle_buffer_size):
        base_dataset = self.datasets[base_dataset_name]

        if batch_size is None:
            batch_size = self.batch_size

        if isinstance(base_dataset, tf.data.Dataset):
            dset = base_dataset
        elif isinstance(base_dataset, Dataset):
            dset = tf.data.TFRecordDataset(base_dataset.filename)
        else:
            raise Exception("Unknown dataset type: {}.".format(base_dataset))

        # --- possibly repeat and/or shuffle --

        if repeat and shuffle_buffer_size > 0:
            try:
                shuffle_and_repeat_func = tf.data.experimental.shuffle_and_repeat
            except AttributeError:
                shuffle_and_repeat_func = tf.contrib.data.shuffle_and_repeat
            shuffle_and_repeat = shuffle_and_repeat_func(self.shuffle_buffer_size)

            dset = dset.apply(shuffle_and_repeat)

        elif shuffle_buffer_size > 0:
            dset = dset.shuffle(self.shuffle_buffer_size)

        # --- batch and parse ---

        dset = dset.batch(batch_size)

        if hasattr(base_dataset, 'parse_example_batch'):
            dset = dset.map(base_dataset.parse_example_batch)

        # --- possibly prefetch to improve performance ---

        if self.prefetch_buffer_size_in_batches > 0:
            if cfg.use_gpu and self.prefetch_to_device:
                # Suggested here: https://github.com/tensorflow/tensorflow/issues/18947#issuecomment-407778515
                dset = (dset.apply(tf.data.experimental.copy_to_device('/gpu:0'))
                            .prefetch(self.prefetch_buffer_size_in_batches))
            else:
                dset = dset.prefetch(self.prefetch_buffer_size_in_batches)

        # --- finalize ---

        iterator = dset.make_initializable_iterator()

        sess = tf.get_default_session()
        handle = sess.run(iterator.string_handle(name="{}_string_handle".format(name)))

        self.iterators_and_handles[name] = (iterator, handle)

        return dset, iterator, handle