decode(received, numECCodewords, erasures) {
			let poly = new ModulusPoly(this.field, received);
			let S = new Int32Array(numECCodewords);
			let error = false;
			for (let i /*int*/ = numECCodewords; i > 0; i--) {
				let evaluation = poly.evaluateAt(this.field.exp(i));
				S[numECCodewords - i] = evaluation;
				if (evaluation !== 0) {
					error = true;
				}
			}
			if (!error) {
				return 0;
			}
			let knownErrors = this.field.getOne();
			if (erasures != null) {
				for (const erasure of erasures) {
					let b = this.field.exp(received.length - 1 - erasure);
					// Add (1 - bx) term:
					let term = new ModulusPoly(this.field, new Int32Array([this.field.subtract(0, b), 1]));
					knownErrors = knownErrors.multiply(term);
				}
			}
			let syndrome = new ModulusPoly(this.field, S);
			// syndrome = syndrome.multiply(knownErrors);
			let sigmaOmega = this.runEuclideanAlgorithm(this.field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);
			let sigma = sigmaOmega[0];
			let omega = sigmaOmega[1];
			// sigma = sigma.multiply(knownErrors);
			let errorLocations = this.findErrorLocations(sigma);
			let errorMagnitudes = this.findErrorMagnitudes(omega, sigma, errorLocations);
			for (let i /*int*/ = 0; i < errorLocations.length; i++) {
				let position = received.length - 1 - this.field.log(errorLocations[i]);
				if (position < 0) {
					throw ChecksumException.getChecksumInstance();
				}
				received[position] = this.field.subtract(received[position], errorMagnitudes[i]);
			}
			return errorLocations.length;
		}
@param received received codewords
@param numECCodewords number of those codewords used for EC
@param erasures location of erasures
@return number of errors
@throws ChecksumException if errors cannot be corrected, maybe because of too many errors