public function classify( $text, $candidates = null ) {
		$results = [];
		$this->resultStatus = '';

		// strip non-word characters before checking for min length, don't assess empty strings
		$wordLength = mb_strlen( preg_replace( "/[{$this->wordSeparator}]+/", "", $text ) );
		if ( $wordLength < $this->minInputLength || $wordLength == 0 ) {
			$this->resultStatus = self::STATUSTOOSHORT;
			return $results;
		}

		$inputgrams = array_keys( $this->createLM( $text, $this->maxNgrams ) );
		if ( $candidates ) {
			// flip for more efficient lookups
			$candidates = array_flip( $candidates );
		}
		foreach ( $this->langFiles as $language => $langFile ) {
			if ( $candidates && !isset( $candidates[$language] ) ) {
				continue;
			}
			$ngrams = $this->loadLanguageFile( $langFile );
			$p = 0;
			foreach ( $inputgrams as $i => $ingram ) {
				if ( !empty( $ngrams[$ingram] ) ) {
					$p += abs( $ngrams[$ingram] - $i );
				} else {
					$p += $this->maxNgrams;
				}
			}
			if ( isset( $this->boostedLangs[$language] ) ) {
				$p = round( $p * ( 1 - $this->langBoostScore ) );
			}
			$results[$language] = $p;
		}

		asort( $results );

		// ignore any item that scores higher than best * resultsRatio
		$max = reset( $results ) * $this->resultsRatio;
		$results = array_filter( $results, function ( $res ) use ( $max ) {
			return $res <= $max;
		} );

		// if more than maxReturnedLanguages remain, the result is too ambiguous, so bail
		if ( count( $results ) > $this->maxReturnedLanguages ) {
			$this->resultStatus = self::STATUSAMBIGUOUS;
			return [];
		}

		// filter max proportion of max score after ambiguity check; reuse $max variable
		$max = count( $inputgrams ) * $this->maxNgrams * $this->maxProportion;
		$results = array_filter( $results, function ( $res ) use ( $max ) {
			return $res <= $max;
		} );

		if ( count( $results ) == 0 ) {
			$this->resultStatus = self::STATUSNOMATCH;
			return $results;
		}

		return $results;
	}