@param string $class
@param string $suffix

@return string
336695
public static function getClassShortName(
        string $class,
        string $suffix = ''
    ): string {
        $baseName = static::getClassBaseName($class);

        return preg_replace(sprintf('/%s$/', $suffix), '', $baseName);
    }
504007
public static ClassName classNameWithSuffix(String packageName, String className, String suffix) {
		return ClassName.get(packageName, className + suffix);
	}
271733
protected function getServiceClassFromNamespaces(
        array $namespaces,
        string $suffix,
        string $directory = null
    ): ?string {
        $serviceClass = null;

        foreach ($namespaces as $namespace) {
            $class = $this->getNamespace($namespace, $suffix, $directory);
            if (class_exists($class) && is_subclass_of($class, XerviceInterface::class)) {
                $serviceClass = $class;
                break;
            }
        }

        return $serviceClass;
    }
900756
public function getBasename($suffix = null)
    {
        if (null === $suffix) {
            $suffix = static::SEPARATOR_EXTENSION.$this->getExtension();
        }

        return parent::getBasename((string)$suffix);
    }
825838
public function loadClass($class)
    {
        $prefix = $class;

        while (($pos = strrpos($prefix, '\\')) !== false) {
            $prefix = substr($class, 0, $pos + 1);
            $relativeClass = substr($class, $pos + 1);

            $mappedFile = $this->_loadMappedFile($prefix, $relativeClass);
            if ($mappedFile) {
                return $mappedFile;
            }

            $prefix = rtrim($prefix, '\\');
        }

        return false;
    }
321851
public function baseNameFilter($path, $suffix = false)
    {
        if ($suffix) {
            $output = basename($path, $suffix);
        } else {
            $output = basename($path);
        }
        return $output;
    }
989703
public function getTemplatesWithSuffix($suffix)
    {
        $templates = SSViewer::get_templates_by_class(get_class($this), $suffix, __CLASS__);
        return SSViewer::chooseTemplate($templates);
    }
316893
public function toAttr($prefix='', $suffix='') {
        $attrs = array();
        if ($this->width !== FALSE) {
            $attrs[] = 'width="'.addslashes($this->width).'"';
        }
        if ($this->height !== FALSE) {
            $attrs[] = 'height="'.addslashes($this->height).'"';
        }
        return $prefix.implode(' ', $attrs).$suffix;
    }
342022
public static function filter_suffixed($array, $suffix, $remove_suffix = true)
    {
        $return = [];
        foreach ($array as $key => $val) {
            if (preg_match('/'.$suffix.'$/', $key)) {
                if ($remove_suffix === true) {
                    $key = preg_replace('/'.$suffix.'$/', '', $key);
                }
                $return[$key] = $val;
            }
        }
        return $return;
    }
1307394
public static function getClassDescription(string $class, string &$resolvedClass = null): string
    {
        $resolvedClass = $class;
        try {
            $resource = new ClassExistenceResource($class, false);

            // isFresh() will explode ONLY if a parent class/trait does not exist
            $resource->isFresh(0);

            $r = new \ReflectionClass($class);
            $resolvedClass = $r->name;

            if ($docComment = $r->getDocComment()) {
                $docComment = preg_split('#\n\s*\*\s*[\n@]#', substr($docComment, 3, -2), 2)[0];

                return trim(preg_replace('#\s*\n\s*\*\s*#', ' ', $docComment));
            }
        } catch (\ReflectionException $e) {
        }

        return '';
    }
887343
public function endsWithIgnoreCase($suffix) {
		$other = new Str($suffix, $this->charset);

		return mb_strripos($this->rawString, $suffix, 0, $this->charset) === ($this->length() - $other->length());
	}
778416
protected static function buildTableName($suffix = '')
    {
        if (true === empty(static::$tablePrefix)) {
            if (strpos(static::tableName(), '}}') !== false) {
                $name = str_replace('}}', $suffix . '}}', static::tableName());
            } else {
                $name = static::tableName() . $suffix;
            }
        } else {
            $name = static::$tablePrefix . $suffix;
        }
        return $name;
    }
824072
public function addUseStatementIfNecessary(string $class): string
    {
        $shortClassName = Str::getShortClassName($class);
        if ($this->isInSameNamespace($class)) {
            return $shortClassName;
        }

        $namespaceNode = $this->getNamespaceNode();

        $targetIndex = null;
        $addLineBreak = false;
        $lastUseStmtIndex = null;
        foreach ($namespaceNode->stmts as $index => $stmt) {
            if ($stmt instanceof Node\Stmt\Use_) {
                // I believe this is an array to account for use statements with {}
                foreach ($stmt->uses as $use) {
                    $alias = $use->alias ? $use->alias->name : $use->name->getLast();

                    // the use statement already exists? Don't add it again
                    if ($class === (string) $use->name) {
                        return $alias;
                    }

                    if ($alias === $shortClassName) {
                        // we have a conflicting alias!
                        // to be safe, use the fully-qualified class name
                        // everywhere and do not add another use statement
                        return '\\'.$class;
                    }
                }

                // if $class is alphabetically before this use statement, place it before
                // only set $targetIndex the first time you find it
                if (null === $targetIndex && Str::areClassesAlphabetical($class, (string) $stmt->uses[0]->name)) {
                    $targetIndex = $index;
                }

                $lastUseStmtIndex = $index;
            } elseif ($stmt instanceof Node\Stmt\Class_) {
                if (null !== $targetIndex) {
                    // we already found where to place the use statement

                    break;
                }

                // we hit the class! If there were any use statements,
                // then put this at the bottom of the use statement list
                if (null !== $lastUseStmtIndex) {
                    $targetIndex = $lastUseStmtIndex + 1;
                } else {
                    $targetIndex = $index;
                    $addLineBreak = true;
                }

                break;
            }
        }

        if (null === $targetIndex) {
            throw new \Exception('Could not find a class!');
        }

        $newUseNode = (new Builder\Use_($class, Node\Stmt\Use_::TYPE_NORMAL))->getNode();
        array_splice(
            $namespaceNode->stmts,
            $targetIndex,
            0,
            $addLineBreak ? [$newUseNode, $this->createBlankLineNode(self::CONTEXT_OUTSIDE_CLASS)] : [$newUseNode]
        );

        $this->updateSourceCodeFromNewStmts();

        return $shortClassName;
    }
41590
protected function setSuffix($suffix)
    {
        if (is_null($suffix) or is_bool($suffix)) {
            $this->suffix = null;
        } elseif ($suffix === '/') {
            $this->suffix = $suffix;
        } else {
            $this->suffix = '.' . trim($suffix, '.');
        }
    }
747477
protected function baseUrlPath($suffix = null, array $query = [])
    {
        /** @var string $baseUrlPath */
        $baseUrlPath = $this->baseUrlPath;

        if (!empty($suffix)) {
            $suffix = ltrim($suffix, "\/");
            $baseUrlPath .= '/' . trim($suffix);
        }

        if (!empty($query)) {
            $queryString  = http_build_query($query);
            $baseUrlPath .= '?' . $queryString;
        }

        return $baseUrlPath;
    }
229904
public static function tableize($class)
    {
        $underscored = Strings::camelCaseToUnderscore($class);
        $parts = explode('_', $underscored);
        $suffix = Inflector::pluralize(array_pop($parts));
        $parts[] = $suffix;
        return implode('_', $parts);
    }
68251
protected function className($suffix = '') {
		$exp = explode('\\', $this->getClass());

		return (!empty($suffix) &&
			substr($exp[count($exp) - 1], (strlen($exp[count($exp) - 1]) - strlen($suffix))) === $suffix) ?
			substr($exp[count($exp) - 1], 0, (strlen($exp[count($exp) - 1]) - strlen($suffix))) :
			$exp[count($exp) - 1];
	}