protected function getGenerator()
    {
        if (isset($this->generator)) {
            return $this->generator;
        }

        if ($this->entity instanceof SnapshotGeneratorProviderInterface) {
            $serviceLocator = $this->getServicelocator();

            // the snapshotgenerator is a service defined by the name of the entity
            // this is the highest means, all subsequent means just add what is not set
            $className = get_class($this->entity);
            if ($serviceLocator->has('snapshotgenerator' . $className)) {
                $generator = $this->serviceLocator->get('snapshotgenerator' . $className);
                if (is_array($generator)) {
                    $this->options = ArrayUtils::merge($generator, $this->options);
                    $generator = null;
                }
            }

            // the snapshotgenerator is provided by the entity
            // this can either be a generator-entity of a array with options
            if (!isset($generator)) {
                $generator = $this->entity->getSnapshotGenerator();
                if (is_array($generator)) {
                    $this->options = ArrayUtils::merge($generator, $this->options);
                    if (array_key_exists('generator', $generator)) {
                        $generator = $this->options['generator'];
                        unset($this->options['generator']);
                    } else {
                        $generator = null;
                    }
                }
                if (is_string($generator)) {
                    $generator = $serviceLocator->get($generator);
                }
            }

            // the last possibility to get a generator
            if (!isset($generator)) {
                // defaultGenerator
                $generator = new SnapshotGenerator();
            }

            // *** filling the options
            // hydrator
            // can be a class, but if it's a string, consider it to be an hydrator in the hydratormanager
            if (array_key_exists('hydrator', $this->options)) {
                $hydrator = $this->options['hydrator'];
                if (is_string($hydrator) && !empty($hydrator)) {
                    $hydrator = $serviceLocator->get('HydratorManager')->get($hydrator);
                }
                $generator->setHydrator($hydrator);
            }

            // exclude
            // add the elements, that should not be transferred
            if (array_key_exists('exclude', $this->options)) {
                // it is very likely that the hydrator is set by the snapshot-class,
                // so we have to asume, that may know the hydrator
                $hydrator = $generator->getHydrator();
                $exclude = $this->options['exclude'];
                if (is_array($exclude)) {
                    $hydrator->setExcludeMethods($exclude);
                }
            }
            $generator->setSource($this->entity);
            $this->generator = $generator;
        }
        return $this->generator;
    }