set(newValue, options = null, saveChangeToHistory = true) {
        //TODO Add the `saveSettings` options. If `true`, then when `options` is passed, then it overwrite the current `this.settings`. If `false` the `options` are only used once and `this.settings` is not modified
        if (AutoNumericHelper.isUndefined(newValue)) {
            AutoNumericHelper.warning(`You are trying to set an 'undefined' value ; an error could have occurred.`, this.settings.showWarnings);
            return this;
        }

        // The options update is done only if the `newValue` is not `undefined`
        if (!AutoNumericHelper.isNull(options)) {
            this._setSettings(options, true); // We do not call `update` here since this would call `set` too
        }

        if (newValue === null && this.settings.emptyInputBehavior !== AutoNumeric.options.emptyInputBehavior.null) {
            AutoNumericHelper.warning(`You are trying to set the \`null\` value while the \`emptyInputBehavior\` option is set to ${this.settings.emptyInputBehavior}. If you want to be able to set the \`null\` value, you need to change the 'emptyInputBehavior' option to \`'null'\`.`, this.settings.showWarnings);
            return this;
        }

        let value;
        if (newValue === null) {
            //TODO Merge this into a global `if (newValue === null) {` test, with the test above
            // Here this.settings.emptyInputBehavior === AutoNumeric.options.emptyInputBehavior.null
            this._setElementAndRawValue(null, null, saveChangeToHistory);
            this._saveValueToPersistentStorage();

            return this;
        }

        value = this.constructor._toNumericValue(newValue, this.settings);
        if (isNaN(Number(value))) {
            //TODO Do not modify the element value if the newValue results in `NaN`. Make sure the settings, if modified, are revert back too.
            AutoNumericHelper.warning(`The value you are trying to set results in \`NaN\`. The element value is set to the empty string instead.`, this.settings.showWarnings);
            this.setValue('', saveChangeToHistory);

            return this;
        }

        if (value === '') {
            switch (this.settings.emptyInputBehavior) {
                case AutoNumeric.options.emptyInputBehavior.zero:
                    value = 0;
                    break;
                case AutoNumeric.options.emptyInputBehavior.min:
                    value = this.settings.minimumValue;
                    break;
                case AutoNumeric.options.emptyInputBehavior.max:
                    value = this.settings.maximumValue;
                    break;
                default:
                    if (AutoNumericHelper.isNumber(this.settings.emptyInputBehavior)) {
                        value = Number(this.settings.emptyInputBehavior);
                    }
            }
        }

        if (value !== '') {
            const [minTest, maxTest] = this.constructor._checkIfInRangeWithOverrideOption(value, this.settings);

            // Modify the formatted value if the rawValue is found in the `valuesToStrings` option
            if (minTest && maxTest && this.settings.valuesToStrings && this._checkValuesToStrings(value)) {
                // Set the raw value normally, and the formatted value with the corresponding string
                this._setElementAndRawValue(this.settings.valuesToStrings[value], value, saveChangeToHistory);
                this._saveValueToPersistentStorage();

                return this;
            }

            // This test is needed by the `showPositiveSign` option
            const isZero = AutoNumericHelper.isZeroOrHasNoValue(value);
            if (isZero) {
                value = '0';
            }

            if (minTest && maxTest) {
                let forcedRawValue = this.constructor._roundRawValue(value, this.settings);
                forcedRawValue = this._trimLeadingAndTrailingZeros(forcedRawValue.replace(this.settings.decimalCharacter, '.')); // Move the `setRawValue` call after the `setElementValue` one
                value = this._getRawValueToFormat(value); // Multiply the raw value to obtain the formatted value

                // Round the given value according to the object state (focused/unfocused)
                if (this.isFocused) {
                    value = this.constructor._roundFormattedValueShownOnFocus(value, this.settings);
                } else {
                    if (this.settings.divisorWhenUnfocused) {
                        value = value / this.settings.divisorWhenUnfocused;
                        value = value.toString();
                    }

                    value = this.constructor._roundFormattedValueShownOnBlur(value, this.settings);
                }

                value = this.constructor._modifyNegativeSignAndDecimalCharacterForFormattedValue(value, this.settings);
                value = this.constructor._addGroupSeparators(value, this.settings, this.isFocused, this.rawValue, forcedRawValue);
                if (!this.isFocused && this.settings.symbolWhenUnfocused) {
                    value = `${value}${this.settings.symbolWhenUnfocused}`;
                }

                if (this.settings.decimalPlacesShownOnFocus || this.settings.divisorWhenUnfocused) {
                    this._saveValueToPersistentStorage();
                }

                this._setElementAndRawValue(value, forcedRawValue, saveChangeToHistory);

                // Special case when the user is allowed to enter invalid numbers outside the min/max range
                this._setValidOrInvalidState(forcedRawValue);

                return this;
            } else {
                this._triggerRangeEvents(minTest, maxTest);
                AutoNumericHelper.throwError(`The value [${value}] being set falls outside of the minimumValue [${this.settings.minimumValue}] and maximumValue [${this.settings.maximumValue}] range set for this element`);

                this._removeValueFromPersistentStorage();
                this.setValue('', saveChangeToHistory); //TODO Shouldn't we just drop that faulty newValue and keep the previous one? This is behind a `throwError()` call anyway..

                return this;
            }
        } else {
            // Here, `value` equal the empty string `''`
            let result;
            if (this.settings.emptyInputBehavior === AutoNumeric.options.emptyInputBehavior.always) {
                // Keep the currency symbol as per emptyInputBehavior
                result = this.settings.currencySymbol;
            } else {
                result = '';
            }

            this._setElementAndRawValue(result, '', saveChangeToHistory);

            return this;
        }
    }
Set the given element value, and format it immediately.
Additionally, this `set()` method can accept options that will be merged into the current AutoNumeric element, taking precedence over any previous settings.

@example anElement.set('12345.67') // Formats the value
@example anElement.set(12345.67) // Formats the value
@example anElement.set(12345.67, { decimalCharacter : ',' }) // Update the settings and formats the value in one go
@example anElement.northAmerican().set('$12,345.67') // Set an already formatted value (this does not _exactly_ respect the currency symbol/negative placements, but only remove all non-numbers characters, according to the ones given in the settings)
@example anElement.set(null) // Set the rawValue and element value to `null`

@param {number|string|null} newValue The value must be a Number, a numeric string or `null` (if `emptyInputBehavior` is set to `'null'`)
@param {object} options A settings object that will override the current settings. Note: the update is done only if the `newValue` is defined.
@param {boolean} saveChangeToHistory If set to `true`, then the change is recorded in the history table
@returns {AutoNumeric}
@throws