internal static bool IsJsonConfigModelValid(StandAloneInstallerJsonModelBase config, StandAloneInstallerJsonModelBase oldConfig, bool validateDownNodes, bool throwIfError = false)
        {
            try
            {
                config.ThrowValidationExceptionIfNull(StringResources.Error_BPAJsonModelInvalid);
                config.ValidateModel();
                var settingsValidator = new StandaloneSettingsValidator(config);
                settingsValidator.Validate(validateDownNodes);

                // UOS validates upgrade config diffs by calling ValidateUpdateFrom() method directly. Test-Configuration invokes IsJsonConfigModelValid() and it calls ValidateUpdateFrom inside.
                // The reason is from Test-Configuration, there is no cluster connection, so that we ignore ValidateTopologyAsync(). Therefore in the ValidateUpdateFrom here there is no need
                // to await the async call. However in UOS, we should call ValidateUpdateFrom in an async manner. That's why I am not trying to have the UOS/TestConfiguration going down the same path.
                if (oldConfig != null)
                {
                    settingsValidator.ValidateUpdateFrom(oldConfig.GetUserConfig(), oldConfig.GetClusterTopology(), connectedToCluster: false).GetAwaiter().GetResult();
                }
            }
            catch (FileNotFoundException ex)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPAPackageFileNotFound, ex.ToString());
                return(false);
            }
            catch (ValidationException ex)
            {
                SFDeployerTrace.WriteError(StringResources.Error_BPAModelSettingsValidationFailed, ex.GetMessage(System.Globalization.CultureInfo.InvariantCulture));
                if (throwIfError)
                {
                    throw;
                }

                return(false);
            }

            return(true);
        }