public function setValue($entity, $value)
    {
        if (false === ($entity instanceof $this->class)) {
            // FIXXME Improve this message
            throw new \Exception(
                "Can't set the entity's {$this->name} property as the entity is not an instance of {$this->class}."
            );
        }

        if (!is_array($value) && !($value instanceof \Traversable)) {
            if ((null !== $this->adderRemover) && (null !== $this->getter)) {
                // Use iterator_to_array() instead of clone in order to prevent side effects
                // see https://github.com/symfony/symfony/issues/4670
                $itemsToAdd = is_object($value) ? iterator_to_array($value) : $value;
                $itemToRemove = array();
                $previousValue = $this->getValue($entity);

                if (is_array($previousValue) || $previousValue instanceof \Traversable) {
                    foreach ($previousValue as $previousItem) {
                        foreach ($value as $key => $item) {
                            if ($item === $previousItem) {
                                // Item found, don't add
                                unset($itemsToAdd[$key]);

                                // Next $previousItem
                                continue 2;
                            }
                        }

                        // Item not found, add to remove list
                        $itemToRemove[] = $previousItem;
                    }
                }

                foreach ($itemToRemove as $item) {
                    call_user_func(array($entity, 'remove' . $this->adderRemover), $item);
                }

                foreach ($itemsToAdd as $item) {
                    call_user_func(array($entity, 'add' . $this->adderRemover), $item);
                }

                return;
            }
        }

        if (null === $this->setter) {
            // FIXXME Improve this message
            throw new \Exception(
                "Can't set the entity's {$this->name} property as no setter has been found."
            );
        }

        if (self::GETTER_SETTER_METHOD === $this->setterType) {
            return $entity->{$this->setter}($value);
        } else {
            return $entity->{$this->setter} = $value;
        }
    }