<?php

/*
 * @author TRYDEA - 2024
 */

namespace Shared\Authentication\Entity;

use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\ExistsFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Serializer\Filter\GroupFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
use Shared\Authentication\CustomFilters\DeletedFilter;
use Shared\RightManagement\Controller\DeleteSiteAction;
use Shared\Utils\ArrayCollectionUtils;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Webapp\Core\Entity\AbstractVariable;
use Webapp\Core\Entity\Device;
use Webapp\Core\Entity\Experiment;
use Webapp\Core\Entity\Factor;
use Webapp\Core\Entity\GeneratorVariable;
use Webapp\Core\Entity\GraphicalConfiguration;
use Webapp\Core\Entity\OezNature;
use Webapp\Core\Entity\OpenSilexInstance;
use Webapp\Core\Entity\Platform;
use Webapp\Core\Entity\Protocol;
use Webapp\Core\Entity\SemiAutomaticVariable;
use Webapp\Core\Entity\SimpleVariable;
use Webapp\Core\Entity\StateCode;
use Webapp\Core\Entity\UserGroup;
use Webapp\Core\Entity\ValueList;
use Webapp\FileManagement\Entity\ParsingJob;

/**
 * @ApiResource(
 *     collectionOperations={
 *         "get"={},
 *         "post"={
 *              "security_post_denormalize"="is_granted('SITE_POST', object)",
 *              "denormalization_context"={"groups"={"site_post"}}
 *          },
 *     },
 *     itemOperations={
 *         "get"={"security"="is_granted('SITE_GET', object)"},
 *         "put"={"security"="is_granted('SITE_EDIT', object)"},
 *         "patch"={"security"="is_granted('SITE_EDIT', object)"},
 *         "delete"={
 *              "controller"=DeleteSiteAction::class,
 *              "security"="is_granted('SITE_DELETE', object)"
 *          },
 *     }
 * )
 *
 * @ApiFilter(OrderFilter::class, properties={"label"}, arguments={"orderParameterName"="order"})
 * @ApiFilter(SearchFilter::class, properties={"label": "ipartial", "id": "exact", "userRoles": "exact", "userRoles.user": "exact"})
 * @ApiFilter(ExistsFilter::class, properties={"userRoles", "deletedAt"})
 * @ApiFilter(GroupFilter::class, arguments={"whitelist"={
 *     "design_explorer_view",
 *     "admin_explorer_view",
 *     "project_explorer_view",
 *     "data_explorer_view",
 *     "transfer_explorer_view",
 *     "id_read",
 *     "user_admin_liste"
 * }})
 * @ApiFilter(DeletedFilter::class)
 *
 * @Gedmo\SoftDeleteable()
 *
 * @ORM\Entity(repositoryClass="Shared\Authentication\Repository\SiteRepository")
 *
 * @ORM\Table(name="ado_site", schema="shared")
 */
class Site extends IdentifiedEntity
{
    use SoftDeleteableEntity;

    /**
     * @Groups({"site_post", "user_admin_liste", "change_report", "data_entry_synthesis", "platform_synthesis", "protocol_synthesis", "project_synthesis", "variable_synthesis"})
     *
     * @Assert\NotBlank()
     *
     * @ORM\Column(name="label", type="string", length=255, unique=true)
     */
    private string $label = '';

    /**
     * @var Collection<int, RelUserSite>
     *
     * @Groups({"site_post", "user_admin_liste"})
     *
     * @ORM\OneToMany(targetEntity="Shared\Authentication\Entity\RelUserSite", mappedBy="site", cascade={"remove", "persist"})
     */
    private Collection $userRoles;

    /**
     * @var Collection<int, Factor>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\Factor", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"design_explorer_view"})
     */
    private Collection $factors;

    /**
     * @var Collection<int, Protocol>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\Protocol", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"design_explorer_view"})
     */
    private Collection $protocols;

    /**
     * @var Collection<int, UserGroup>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\UserGroup", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"admin_explorer_view"})
     */
    private Collection $userGroups;

    /**
     * @var Collection<int, Experiment>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\Experiment", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"design_explorer_view"})
     */
    private Collection $experiments;

    /**
     * @var Collection<int, Platform>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\Platform", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"design_explorer_view", "project_explorer_view", "data_explorer_view"})
     */
    private Collection $platforms;

    /**
     * @var Collection<int, SimpleVariable>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\SimpleVariable", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"project_explorer_view"})
     */
    private Collection $simpleVariables;

    /**
     * @var Collection<int, GeneratorVariable>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\GeneratorVariable", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"project_explorer_view"})
     */
    private Collection $generatorVariables;

    /**
     * @var Collection<int, ValueList>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\ValueList", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"project_explorer_view"})
     */
    private Collection $valueLists;

    /**
     * @var Collection<int, StateCode>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\StateCode", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"project_explorer_view"})
     */
    private Collection $stateCodes;

    /**
     * @var Collection<int, Device>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\Device", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"project_explorer_view"})
     */
    private Collection $devices;

    /**
     * @var Collection<int, OezNature>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\OezNature", mappedBy="site", cascade={"remove", "persist"})
     *
     * @Groups({"design_explorer_view"})
     */
    private Collection $oezNatures;

    /**
     * @var Collection<int, ParsingJob>
     *
     * @ApiSubresource()
     *
     * @ORM\OneToMany(targetEntity="Webapp\FileManagement\Entity\ParsingJob", mappedBy="site", cascade={"remove", "persist"})
     */
    private Collection $parsingJobs;

    /**
     * @ORM\OneToOne(targetEntity="Webapp\Core\Entity\GraphicalConfiguration", mappedBy="site", cascade={"remove"})
     */
    private ?GraphicalConfiguration $graphicalConfiguration = null;

    /**
     * @var Collection<int, OpenSilexInstance>
     *
     * @ORM\OneToMany(targetEntity="Webapp\Core\Entity\OpenSilexInstance", mappedBy="site", cascade={"remove"})
     *
     * @Groups({"design_explorer_view", "project_explorer_view", "data_explorer_view", "admin_explorer_view"})
     */
    private Collection $openSilexInstances;

    public function __construct()
    {
        $this->userRoles = new ArrayCollection();
        $this->factors = new ArrayCollection();
        $this->protocols = new ArrayCollection();
        $this->userGroups = new ArrayCollection();
        $this->experiments = new ArrayCollection();
        $this->platforms = new ArrayCollection();
        $this->simpleVariables = new ArrayCollection();
        $this->generatorVariables = new ArrayCollection();
        $this->valueLists = new ArrayCollection();
        $this->stateCodes = new ArrayCollection();
        $this->devices = new ArrayCollection();
        $this->oezNatures = new ArrayCollection();
        $this->openSilexInstances = new ArrayCollection();
    }

    /**
     * @return array<array-key, GeneratorVariable|SemiAutomaticVariable|SimpleVariable>
     */
    public function getVariables(): array
    {
        return array_merge(
            $this->getSimpleVariables()->getValues(),
            array_reduce($this->getDevices()->getValues(), function ($acc, Device $device) {
                return array_merge($acc, $device->getManagedVariables()->getValues());
            }, []),
            $this->getGeneratorVariables()->getValues());
    }

    /**
     * @psalm-mutation-free
     */
    public function getLabel(): string
    {
        return $this->label;
    }

    /**
     * @return $this
     */
    public function setLabel(string $label): self
    {
        $this->label = $label;

        return $this;
    }

    /**
     * @return Collection<int,  RelUserSite>
     *
     * @psalm-mutation-free
     */
    public function getUserRoles(): Collection
    {
        return $this->userRoles;
    }

    /**
     * @param iterable<int, RelUserSite> $userRoles
     *
     * @return $this
     */
    public function setUserRoles(iterable $userRoles): self
    {
        ArrayCollectionUtils::update($this->userRoles, $userRoles, function (RelUserSite $relUserSite) {
            $relUserSite->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addUserRole(RelUserSite $operator): self
    {
        if (!$this->userRoles->contains($operator)) {
            $this->userRoles->add($operator);
            $operator->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeUserRole(RelUserSite $operator): self
    {
        if ($this->userRoles->contains($operator)) {
            $this->userRoles->removeElement($operator);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Factor>
     *
     * @psalm-mutation-free
     */
    public function getFactors(): Collection
    {
        return $this->factors;
    }

    /**
     * @param iterable<int, Factor> $factors
     *
     * @return $this
     */
    public function setFactors(iterable $factors): self
    {
        ArrayCollectionUtils::update($this->factors, $factors, function (Factor $factor) {
            $factor->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addFactor(Factor $factor): self
    {
        if (!$this->factors->contains($factor)) {
            $this->factors->add($factor);
            $factor->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeFactor(Factor $factor): self
    {
        if ($this->factors->contains($factor)) {
            $this->factors->removeElement($factor);
            $factor->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Protocol>
     *
     * @psalm-mutation-free
     */
    public function getProtocols(): Collection
    {
        return $this->protocols;
    }

    /**
     * @param iterable<int, Protocol> $protocols
     *
     * @return $this
     */
    public function setProtocols(iterable $protocols): self
    {
        ArrayCollectionUtils::update($this->protocols, $protocols, function (Protocol $protocol) {
            $protocol->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addProtocol(Protocol $protocol): self
    {
        if (!$this->protocols->contains($protocol)) {
            $this->protocols->add($protocol);
            $protocol->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeProtocol(Protocol $protocol): self
    {
        if ($this->protocols->contains($protocol)) {
            $this->protocols->removeElement($protocol);
            $protocol->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  UserGroup>
     *
     * @psalm-mutation-free
     */
    public function getUserGroups(): Collection
    {
        return $this->userGroups;
    }

    /**
     * @param iterable<int, UserGroup> $userGroups
     *
     * @return $this
     */
    public function setUserGroups(iterable $userGroups): self
    {
        ArrayCollectionUtils::update($this->userGroups, $userGroups, function (UserGroup $userGroup) {
            $userGroup->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addUserGroup(UserGroup $userGroup): self
    {
        if (!$this->userGroups->contains($userGroup)) {
            $this->userGroups->add($userGroup);
            $userGroup->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeUserGroup(UserGroup $userGroup): self
    {
        if ($this->userGroups->contains($userGroup)) {
            $this->userGroups->removeElement($userGroup);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Experiment>
     *
     * @psalm-mutation-free
     */
    public function getExperiments(): Collection
    {
        return $this->experiments;
    }

    /**
     * @param iterable<int, Experiment> $experiments
     *
     * @return $this
     */
    public function setExperiments(iterable $experiments): self
    {
        ArrayCollectionUtils::update($this->experiments, $experiments, function (Experiment $experiment) {
            $experiment->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addExperiment(Experiment $experiment): self
    {
        if (!$this->experiments->contains($experiment)) {
            $this->experiments->add($experiment);
            $experiment->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeExperiment(Experiment $experiment): self
    {
        if ($this->experiments->contains($experiment)) {
            $this->experiments->removeElement($experiment);
            $experiment->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Platform>
     *
     * @psalm-mutation-free
     */
    public function getPlatforms(): Collection
    {
        return $this->platforms;
    }

    /**
     * @param iterable<int, Platform> $platforms
     *
     * @return $this
     */
    public function setPlatforms(iterable $platforms): self
    {
        ArrayCollectionUtils::update($this->platforms, $platforms, function (Platform $platform) {
            $platform->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addPlatform(Platform $platform): self
    {
        if (!$this->platforms->contains($platform)) {
            $this->platforms->add($platform);
            $platform->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removePlatform(Platform $platform): self
    {
        if ($this->platforms->contains($platform)) {
            $this->platforms->removeElement($platform);
        }

        return $this;
    }

    /**
     * @return Collection<int,  SimpleVariable>
     *
     * @psalm-mutation-free
     */
    public function getSimpleVariables(): Collection
    {
        return $this->simpleVariables;
    }

    /**
     * @param iterable<array-key, SimpleVariable> $simpleVariables
     *
     * @return $this
     */
    public function setSimpleVariables(iterable $simpleVariables): self
    {
        ArrayCollectionUtils::update($this->simpleVariables, $simpleVariables, function (SimpleVariable $simpleVariable) {
            $simpleVariable->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addSimpleVariable(SimpleVariable $simpleVariable): self
    {
        if (!$this->simpleVariables->contains($simpleVariable)) {
            $this->simpleVariables->add($simpleVariable);
            $simpleVariable->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeSimpleVariable(SimpleVariable $simpleVariable): self
    {
        if ($this->simpleVariables->contains($simpleVariable)) {
            $this->simpleVariables->removeElement($simpleVariable);
            $simpleVariable->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  GeneratorVariable>
     *
     * @psalm-mutation-free
     */
    public function getGeneratorVariables(): Collection
    {
        return $this->generatorVariables;
    }

    /**
     * @param iterable<array-key, GeneratorVariable> $generatorVariables
     *
     * @return $this
     */
    public function setGeneratorVariables(iterable $generatorVariables): self
    {
        ArrayCollectionUtils::update($this->generatorVariables, $generatorVariables, function (GeneratorVariable $generatorVariable) {
            $generatorVariable->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addGeneratorVariable(GeneratorVariable $generatorVariable): self
    {
        if (!$this->generatorVariables->contains($generatorVariable)) {
            $this->generatorVariables->add($generatorVariable);
            $generatorVariable->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeGeneratorVariable(GeneratorVariable $generatorVariable): self
    {
        if ($this->generatorVariables->contains($generatorVariable)) {
            $this->generatorVariables->removeElement($generatorVariable);
            $generatorVariable->setSite(null);
        }

        return $this;
    }

    /**
     * @param AbstractVariable[] $variables
     *
     * @return $this
     */
    public function setVariables(array $variables): self
    {
        $this->setSimpleVariables(array_filter($variables, fn (AbstractVariable $variable) => $variable instanceof SimpleVariable));
        $this->setGeneratorVariables(array_filter($variables, fn (AbstractVariable $variable) => $variable instanceof GeneratorVariable));

        return $this;
    }

    /**
     * @param SimpleVariable|GeneratorVariable $variable
     *
     * @return $this
     */
    public function addVariable(AbstractVariable $variable): self
    {
        if ($variable instanceof SimpleVariable) {
            $this->addSimpleVariable($variable);
        } elseif ($variable instanceof GeneratorVariable) {
            $this->addGeneratorVariable($variable);
        }

        return $this;
    }

    /**
     * @return Collection<int,  ValueList>
     *
     * @psalm-mutation-free
     */
    public function getValueLists(): Collection
    {
        return $this->valueLists;
    }

    /**
     * @param iterable<int, ValueList> $valueLists
     *
     * @return $this
     */
    public function setValueLists(iterable $valueLists): self
    {
        ArrayCollectionUtils::update($this->valueLists, $valueLists, function (ValueList $valueList) {
            $valueList->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addValueList(ValueList $valueList): self
    {
        if (!$this->valueLists->contains($valueList)) {
            $this->valueLists->add($valueList);
            $valueList->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeValueList(ValueList $valueList): self
    {
        if ($this->valueLists->contains($valueList)) {
            $this->valueLists->removeElement($valueList);
            $valueList->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  Device>
     *
     * @psalm-mutation-free
     */
    public function getDevices(): Collection
    {
        return $this->devices;
    }

    /**
     * @param iterable<int, Device> $devices
     *
     * @return $this
     */
    public function setDevices(iterable $devices): self
    {
        ArrayCollectionUtils::update($this->devices, $devices, function (Device $device) {
            $device->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addDevice(Device $device): self
    {
        if (!$this->devices->contains($device)) {
            $this->devices->add($device);
            $device->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeDevice(Device $device): self
    {
        if ($this->devices->contains($device)) {
            $this->devices->removeElement($device);
            $device->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  StateCode>
     *
     * @psalm-mutation-free
     */
    public function getStateCodes(): Collection
    {
        return $this->stateCodes;
    }

    /**
     * @param iterable<int,  StateCode> $stateCodes
     *
     * @return $this
     */
    public function setStateCodes(iterable $stateCodes): self
    {
        ArrayCollectionUtils::update($this->stateCodes, $stateCodes, function (StateCode $stateCode) {
            $stateCode->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addStateCode(StateCode $stateCode): self
    {
        if (!$this->stateCodes->contains($stateCode)) {
            $this->stateCodes->add($stateCode);
            $stateCode->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeStateCode(StateCode $stateCode): self
    {
        if ($this->stateCodes->contains($stateCode)) {
            $this->stateCodes->removeElement($stateCode);
            $stateCode->setSite(null);
        }

        return $this;
    }

    /**
     * @return Collection<int,  OezNature>
     *
     * @psalm-mutation-free
     */
    public function getOezNatures(): Collection
    {
        return $this->oezNatures;
    }

    /**
     * @param iterable<int, OezNature> $oezNatures
     *
     * @return $this
     */
    public function setOezNatures(iterable $oezNatures): self
    {
        ArrayCollectionUtils::update($this->oezNatures, $oezNatures, function (OezNature $oezNature) {
            $oezNature->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addOezNature(OezNature $oezNature): self
    {
        if (!$this->oezNatures->contains($oezNature)) {
            $this->oezNatures->add($oezNature);
            $oezNature->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeOezNature(OezNature $oezNature): self
    {
        if ($this->oezNatures->contains($oezNature)) {
            $this->oezNatures->removeElement($oezNature);
        }

        return $this;
    }

    /**
     * @return Collection<int,  ParsingJob>
     *
     * @psalm-mutation-free
     */
    public function getParsingJobs(): Collection
    {
        return $this->parsingJobs;
    }

    /**
     * @param iterable<int, ParsingJob> $parsingJobs
     *
     * @return $this
     */
    public function setParsingJobs(iterable $parsingJobs): self
    {
        ArrayCollectionUtils::update($this->parsingJobs, $parsingJobs, function (ParsingJob $parsingJob) {
            $parsingJob->setSite($this);
        });

        return $this;
    }

    /**
     * @psalm-mutation-free
     */
    public function getGraphicalConfiguration(): ?GraphicalConfiguration
    {
        return $this->graphicalConfiguration;
    }

    /**
     * @return $this
     */
    public function setGraphicalConfiguration(?GraphicalConfiguration $graphicalConfiguration): self
    {
        $this->graphicalConfiguration = $graphicalConfiguration;

        return $this;
    }

    /**
     * @return Collection<int,  OpenSilexInstance>
     *
     * @psalm-mutation-free
     */
    public function getOpenSilexInstances(): Collection
    {
        return $this->openSilexInstances;
    }

    /**
     * @param iterable<int, OpenSilexInstance> $openSilexInstances
     *
     * @return $this
     */
    public function setOpenSilexInstances(iterable $openSilexInstances): self
    {
        ArrayCollectionUtils::update($this->openSilexInstances, $openSilexInstances, function (OpenSilexInstance $openSilexInstance) {
            $openSilexInstance->setSite($this);
        });

        return $this;
    }

    /**
     * @return $this
     */
    public function addOpenSilexInstance(OpenSilexInstance $openSilexInstance): self
    {
        if (!$this->openSilexInstances->contains($openSilexInstance)) {
            $this->openSilexInstances->add($openSilexInstance);
            $openSilexInstance->setSite($this);
        }

        return $this;
    }

    /**
     * @return $this
     */
    public function removeOpenSilexInstance(OpenSilexInstance $openSilexInstance): self
    {
        if ($this->openSilexInstances->contains($openSilexInstance)) {
            $this->openSilexInstances->removeElement($openSilexInstance);
        }

        return $this;
    }
}
