Use a trait and save all methods so in case
a second trait will overwrite any

@param \ReflectionClass $trait

@return $this
328101
public function useTrait(\ReflectionClass $trait)
    {
        $alias = 'trait' . ($this->_traitsIdx++);
        $alias .= '_' . str_replace('\\', '__', $trait->getName());

        $alias = 'Trait_' . substr(md5($alias), 0, 10) . '_' .$trait->getShortName();

        $this->addUse($trait->getName(), $alias);
        $this->addTrait($alias);

        foreach ($trait->getMethods() as $method) {
            if ($method->isAbstract()) {
                continue;
            }
            $this->registerTraitMethod($alias, $method);
        }

        return $this;
    }
618134
protected function trait_child_save() {
		$db = self::trait_get_database();
		$table = self::trait_get_child_database_table();

		if ($table === null) {
			return;
		}

		$count = $db->get_one('SELECT count(*) FROM ' . $db->quote_identifier($table) . ' WHERE ' . self::trait_get_parent_table_field_id() . '=?', [$this->id]);

		$this->child_details[self::trait_get_parent_table_field_id()] = $this->id;
		if ($count == 0) {
			$db->insert($table, $this->child_details);
		} else {
			$where = self::trait_get_parent_table_field_id() . '=' . $db->quote($this->id);
			$db->update($table, $this->child_details, $where);
		}
	}
1042270
public function getTraitImplementingMethod(ReflectionClass $class, string $methodName): ReflectionClass
    {
        $traitsWithMethod = [];
        foreach ($class->getTraits() as $trait) {
            try {
                $trait->getMethod($methodName);
                $traitsWithMethod[] = $trait;
            } catch (\ReflectionException $e) {
            }
        }
        if (count($traitsWithMethod) > 1) {
            throw new \RuntimeException(
                'Found more than one trait implementing the method ' . $methodName . ' in ' .
                $class->getShortName()
            );
        }
        if ([] === $traitsWithMethod) {
            throw new \RuntimeException(
                'Failed finding trait implementing the method ' . $methodName . ' in ' .
                $class->getShortName()
            );
        }

        return current($traitsWithMethod);
    }
274556
protected static function traitsOfTrait($trait)
    {
        $traits = static::traits($trait, false, false);

        foreach ($traits as $usedTrait) {
            $traits += static::traitsOfTrait($usedTrait);
        }

        return $traits;
    }
666207
private function mergeTraitMethods()
    {
        $reflection = $this->__reflection();
        $mergedMethods = [];
        do {
            $staticProperties = $reflection->getStaticProperties();

            if (!isset($staticProperties['___classMocker_traitMethods'])) {
                continue;
            }

            $mergedMethods = array_merge_recursive($mergedMethods, $staticProperties['___classMocker_traitMethods']);
        } while ($reflection = $reflection->getParentClass());

        return $mergedMethods;
    }
408993
public function withMock($mock)
    {
        if (is_string($mock)) {
            $mock = new $mock;
        }

        $this->mock = $mock;

        return $this;
    }
528262
private function getTraitMethods()
    {
        if (!is_array($this->_traitMethods)) {
            $this->_traitMethods = $this->mergeTraitMethods();
        }
        return $this->_traitMethods;
    }
572921
protected function addMethods($methods, $traitDescriptor)
    {
        foreach ($methods as $method) {
            $methodDescriptor = $this->getBuilder()->buildDescriptor($method);
            if ($methodDescriptor) {
                $methodDescriptor->setParent($traitDescriptor);
                $traitDescriptor->getMethods()->set($methodDescriptor->getName(), $methodDescriptor);
            }
        }
    }
756610
private static function _getTraits($class, array $traits = null)
    {
        $rc = $class instanceof \ReflectionClass ? $class : new \ReflectionClass($class);
        if (is_null($traits)) {
            $traits = array();
        }

        // traits being embedded through the current class or the embedded traits
        foreach ($rc->getTraits() as $trait) {
            $traits = self::_getTraits($trait, $traits); // first the embedded traits that come first...
            if (!in_array($trait->name, $traits)) {
                $traits[] = $trait->name;
            }                    // then the current trait
        }

        // traits embedded by the parent class
        if ($rc->getParentClass()) {
            $traits = self::_getTraits($rc->getParentClass(), $traits);
        }

        return $traits;
    }
697260
protected function traitNameExists($trait)
    {
        if($this->files->exists($this->getTraitDirectory() . $this->getDirOption() . $trait . '.php')) {
            return true;
        }

        return false;
    }
199331
public function getNewInstance(\ReflectionClass $class) : NewInstance
    {
        $setterMethods = new SetterMethods([]);
        $methods = $class->getMethods();
        foreach ($methods as $method) {
            if ($method->name === '__construct') {
                continue;
            }
            $setterMethods->add($this->injectionMethod->getSetterMethod($method));
        }
        $name = $this->injectionMethod->getConstructorName($class);

        return new NewInstance($class, $setterMethods, $name);
    }
1209414
public function generateClass(): ClassGenerator
    {
        $interfaces = $this->getInterfaces();
        foreach ($interfaces as $interface) {
            $this->classGenerator->addUse($interface);
        }
        $this->classGenerator->setImplementedInterfaces($interfaces);

        $traits = $this->getTraits();
        foreach ($traits as $trait) {
            $this->classGenerator->addUse($trait);
            $this->classGenerator->addTrait((new \ReflectionClass($trait))->getShortName());
        }

        foreach ($this->metadata->getFieldsMetadata() as $fieldMetadata) {
            $fieldMetadata->generateProxy($this);
        }

        $this->generateBsonUnserializeMethod();

        return $this->classGenerator;
    }
704429
protected function traitsInit()
    {
        $traits = $this->getUsedTraits();
        $reflection = new \ReflectionClass($this);
        foreach($traits as $trait) {
            $methodName = 'initTrait' . $trait;
            if($reflection->hasMethod($methodName)) {
                $this->$methodName();
            }
        }
    }
459449
protected function createTraitFile($trait)
    {
        $dir_option = rtrim(str_replace('/', '\\', $this->getDirOption()), '/\\');
        $dir_option = $dir_option ? '\\' . $dir_option : '';
        $trait = $this->configureName('trait', $trait);

        $stub = str_replace(
            ['{{Namespace}}', '{{TraitName}}'],
            [$this->getTraitDirectoryFromConfig() . $dir_option, $trait],
            $this->files->get(__DIR__ . '/../stubs/trait.stub')
        );

        $this->files->put(base_path() . '/' . $this->getTraitDirectory() . $this->getDirOption() . $trait . '.php', $stub);
    }
563982
protected function createDefinition(\ReflectionClass $reflection): Definition
    {
        $definition = new Definition($reflection->getName());

        foreach ($this->processors as $processor)
        {
            $processor->process($reflection, $definition);
        }

        $parent = $reflection->getParentClass();

        if ($parent !== false) {
            $definition->merge($this->createDefinition($parent));
        }

        foreach ($reflection->getTraits() as $trait)
        {
            $definition->merge($this->createDefinition($trait));
        }

        return $definition;
    }
142013
public function remove(TraitDefinition $traitToRemove)
    {
        foreach ($this->collection as $key => $trait) {
            if ($trait === $traitToRemove) {
                unset($this->collection[$key]);

                return;
            }
        }

        throw new Exception(\sprintf('Cannot remove given trait %s', \var_export($traitToRemove, true)));
    }
1363461
protected function checkTraitDependencies($traitName)
    {
        if(isset($this->traitsDependencies[$traitName])) {
            $reflection = new \ReflectionClass($this);
            foreach($this->traitsDependencies[$traitName] as $requiredTrait) {
                $propertyName = 'has' . $requiredTrait;
                if(!$reflection->hasProperty($propertyName) || !$this->$propertyName) {
                    throw new \Exception(sprintf('Class %s uses %s trait but %s required trait is not used', $this->buildClassName($this->name), $traitName, $requiredTrait));
                }
            }
        }
    }