diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index a56e526a6..6bf512e12 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -328,6 +328,9 @@ add_library(core STATIC
     hle/service/nim/nim.h
     hle/service/npns/npns.cpp
     hle/service/npns/npns.h
+    hle/service/ns/errors.h
+    hle/service/ns/language.cpp
+    hle/service/ns/language.h
     hle/service/ns/ns.cpp
     hle/service/ns/ns.h
     hle/service/ns/pl_u.cpp
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index 60ea9ad12..04da30825 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -87,6 +87,10 @@ u64 NACP::GetDefaultJournalSaveSize() const {
     return raw.user_account_save_data_journal_size;
 }
 
+u32 NACP::GetSupportedLanguages() const {
+    return raw.supported_languages;
+}
+
 std::vector<u8> NACP::GetRawBytes() const {
     std::vector<u8> out(sizeof(RawNACP));
     std::memcpy(out.data(), &raw, sizeof(RawNACP));
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 280710ddf..1be34ed55 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -109,6 +109,7 @@ public:
     std::string GetVersionString() const;
     u64 GetDefaultNormalSaveSize() const;
     u64 GetDefaultJournalSaveSize() const;
+    u32 GetSupportedLanguages() const;
     std::vector<u8> GetRawBytes() const;
 
 private:
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 1a32a109f..3f201c821 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -8,6 +8,8 @@
 #include <cstring>
 #include "audio_core/audio_renderer.h"
 #include "core/core.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
 #include "core/file_sys/savedata_factory.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/kernel/kernel.h"
@@ -29,9 +31,11 @@
 #include "core/hle/service/am/tcap.h"
 #include "core/hle/service/apm/apm.h"
 #include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/ns/ns.h"
 #include "core/hle/service/nvflinger/nvflinger.h"
 #include "core/hle/service/pm/pm.h"
 #include "core/hle/service/set/set.h"
+#include "core/hle/service/sm/sm.h"
 #include "core/hle/service/vi/vi.h"
 #include "core/settings.h"
 
@@ -1100,10 +1104,42 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
     // TODO(bunnei): This should be configurable
     LOG_DEBUG(Service_AM, "called");
 
+    // Get supported languages from NACP, if possible
+    // Default to 0 (all languages supported)
+    u32 supported_languages = 0;
+    FileSys::PatchManager pm{Core::System::GetInstance().CurrentProcess()->GetTitleID()};
+
+    const auto res = pm.GetControlMetadata();
+    if (res.first != nullptr) {
+        supported_languages = res.first->GetSupportedLanguages();
+    }
+
+    // Call IApplicationManagerInterface implementation.
+    auto& service_manager = Core::System::GetInstance().ServiceManager();
+    auto ns_am2 = service_manager.GetService<Service::NS::NS>("ns:am2");
+    auto app_man = ns_am2->GetApplicationManagerInterface();
+
+    // Get desired application language
+    const auto res_lang = app_man->GetApplicationDesiredLanguage(supported_languages);
+    if (res_lang.Failed()) {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(res_lang.Code());
+        return;
+    }
+
+    // Convert to settings language code.
+    const auto res_code = app_man->ConvertApplicationLanguageToLanguageCode(*res_lang);
+    if (res_code.Failed()) {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(res_code.Code());
+        return;
+    }
+
+    LOG_DEBUG(Service_AM, "got desired_language={:016X}", *res_code);
+
     IPC::ResponseBuilder rb{ctx, 4};
     rb.Push(RESULT_SUCCESS);
-    rb.Push(
-        static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index)));
+    rb.Push(*res_code);
 }
 
 void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/ns/errors.h b/src/core/hle/service/ns/errors.h
new file mode 100644
index 000000000..f4aea8a65
--- /dev/null
+++ b/src/core/hle/service/ns/errors.h
@@ -0,0 +1,12 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/result.h"
+
+namespace Service::NS {
+
+constexpr ResultCode ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300};
+}
\ No newline at end of file
diff --git a/src/core/hle/service/ns/language.cpp b/src/core/hle/service/ns/language.cpp
new file mode 100644
index 000000000..29c4a820c
--- /dev/null
+++ b/src/core/hle/service/ns/language.cpp
@@ -0,0 +1,392 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/ns/language.h"
+#include "core/hle/service/set/set.h"
+
+namespace Service::NS {
+
+constexpr ApplicationLanguagePriorityList priority_list_american_english = {{
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_french = {{
+    ApplicationLanguage::French,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_german = {{
+    ApplicationLanguage::German,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_italian = {{
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_russian = {{
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_korean = {{
+    ApplicationLanguage::Korean,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Korean,
+}};
+
+constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
+    ApplicationLanguage::SimplifiedChinese,
+    ApplicationLanguage::TraditionalChinese,
+    ApplicationLanguage::AmericanEnglish,
+    ApplicationLanguage::BritishEnglish,
+    ApplicationLanguage::Japanese,
+    ApplicationLanguage::LatinAmericanSpanish,
+    ApplicationLanguage::CanadianFrench,
+    ApplicationLanguage::French,
+    ApplicationLanguage::German,
+    ApplicationLanguage::Spanish,
+    ApplicationLanguage::Italian,
+    ApplicationLanguage::Dutch,
+    ApplicationLanguage::Portuguese,
+    ApplicationLanguage::Russian,
+    ApplicationLanguage::Korean,
+}};
+
+const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
+    const ApplicationLanguage lang) {
+    switch (lang) {
+    case ApplicationLanguage::AmericanEnglish:
+        return &priority_list_american_english;
+    case ApplicationLanguage::BritishEnglish:
+        return &priority_list_british_english;
+    case ApplicationLanguage::Japanese:
+        return &priority_list_japanese;
+    case ApplicationLanguage::French:
+        return &priority_list_french;
+    case ApplicationLanguage::German:
+        return &priority_list_german;
+    case ApplicationLanguage::LatinAmericanSpanish:
+        return &priority_list_latin_american_spanish;
+    case ApplicationLanguage::Spanish:
+        return &priority_list_spanish;
+    case ApplicationLanguage::Italian:
+        return &priority_list_italian;
+    case ApplicationLanguage::Dutch:
+        return &priority_list_dutch;
+    case ApplicationLanguage::CanadianFrench:
+        return &priority_list_canadian_french;
+    case ApplicationLanguage::Portuguese:
+        return &priority_list_portuguese;
+    case ApplicationLanguage::Russian:
+        return &priority_list_russian;
+    case ApplicationLanguage::Korean:
+        return &priority_list_korean;
+    case ApplicationLanguage::TraditionalChinese:
+        return &priority_list_traditional_chinese;
+    case ApplicationLanguage::SimplifiedChinese:
+        return &priority_list_simplified_chinese;
+    default:
+        return nullptr;
+    }
+}
+
+std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
+    const Set::LanguageCode language_code) {
+    switch (language_code) {
+    case Set::LanguageCode::EN_US:
+        return ApplicationLanguage::AmericanEnglish;
+    case Set::LanguageCode::EN_GB:
+        return ApplicationLanguage::BritishEnglish;
+    case Set::LanguageCode::JA:
+        return ApplicationLanguage::Japanese;
+    case Set::LanguageCode::FR:
+        return ApplicationLanguage::French;
+    case Set::LanguageCode::DE:
+        return ApplicationLanguage::German;
+    case Set::LanguageCode::ES_419:
+        return ApplicationLanguage::LatinAmericanSpanish;
+    case Set::LanguageCode::ES:
+        return ApplicationLanguage::Spanish;
+    case Set::LanguageCode::IT:
+        return ApplicationLanguage::Italian;
+    case Set::LanguageCode::NL:
+        return ApplicationLanguage::Dutch;
+    case Set::LanguageCode::FR_CA:
+        return ApplicationLanguage::CanadianFrench;
+    case Set::LanguageCode::PT:
+        return ApplicationLanguage::Portuguese;
+    case Set::LanguageCode::RU:
+        return ApplicationLanguage::Russian;
+    case Set::LanguageCode::KO:
+        return ApplicationLanguage::Korean;
+    case Set::LanguageCode::ZH_HANT:
+        return ApplicationLanguage::TraditionalChinese;
+    case Set::LanguageCode::ZH_HANS:
+        return ApplicationLanguage::SimplifiedChinese;
+    default:
+        return std::nullopt;
+    }
+}
+
+std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage lang) {
+    switch (lang) {
+    case ApplicationLanguage::AmericanEnglish:
+        return Set::LanguageCode::EN_US;
+    case ApplicationLanguage::BritishEnglish:
+        return Set::LanguageCode::EN_GB;
+    case ApplicationLanguage::Japanese:
+        return Set::LanguageCode::JA;
+    case ApplicationLanguage::French:
+        return Set::LanguageCode::FR;
+    case ApplicationLanguage::German:
+        return Set::LanguageCode::DE;
+    case ApplicationLanguage::LatinAmericanSpanish:
+        return Set::LanguageCode::ES_419;
+    case ApplicationLanguage::Spanish:
+        return Set::LanguageCode::ES;
+    case ApplicationLanguage::Italian:
+        return Set::LanguageCode::IT;
+    case ApplicationLanguage::Dutch:
+        return Set::LanguageCode::NL;
+    case ApplicationLanguage::CanadianFrench:
+        return Set::LanguageCode::FR_CA;
+    case ApplicationLanguage::Portuguese:
+        return Set::LanguageCode::PT;
+    case ApplicationLanguage::Russian:
+        return Set::LanguageCode::RU;
+    case ApplicationLanguage::Korean:
+        return Set::LanguageCode::KO;
+    case ApplicationLanguage::TraditionalChinese:
+        return Set::LanguageCode::ZH_HANT;
+    case ApplicationLanguage::SimplifiedChinese:
+        return Set::LanguageCode::ZH_HANS;
+    default:
+        return std::nullopt;
+    }
+}
+} // namespace Service::NS
\ No newline at end of file
diff --git a/src/core/hle/service/ns/language.h b/src/core/hle/service/ns/language.h
new file mode 100644
index 000000000..e9829f9d2
--- /dev/null
+++ b/src/core/hle/service/ns/language.h
@@ -0,0 +1,45 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <optional>
+#include <string>
+#include "common/common_types.h"
+
+namespace Service::Set {
+enum class LanguageCode : u64;
+}
+
+namespace Service::NS {
+/// This is nn::ns::detail::ApplicationLanguage
+enum class ApplicationLanguage : u8 {
+    AmericanEnglish = 0,
+    BritishEnglish,
+    Japanese,
+    French,
+    German,
+    LatinAmericanSpanish,
+    Spanish,
+    Italian,
+    Dutch,
+    CanadianFrench,
+    Portuguese,
+    Russian,
+    Korean,
+    TraditionalChinese,
+    SimplifiedChinese,
+    Count
+};
+using ApplicationLanguagePriorityList =
+    const std::array<ApplicationLanguage, static_cast<std::size_t>(ApplicationLanguage::Count)>;
+
+constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
+    return 1U << static_cast<u32>(lang);
+}
+
+const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
+std::optional<ApplicationLanguage> ConvertToApplicationLanguage(Set::LanguageCode language_code);
+std::optional<Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
+} // namespace Service::NS
\ No newline at end of file
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 0eb04037a..ce88a2941 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -7,445 +7,507 @@
 #include "core/file_sys/patch_manager.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/ns/errors.h"
+#include "core/hle/service/ns/language.h"
 #include "core/hle/service/ns/ns.h"
 #include "core/hle/service/ns/pl_u.h"
+#include "core/hle/service/set/set.h"
+#include "core/settings.h"
 
 namespace Service::NS {
 
-class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
-public:
-    explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {0, nullptr, "CreateUserAccount"},
-        };
-        // clang-format on
+IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "CreateUserAccount"},
+    };
+    // clang-format on
 
-        RegisterHandlers(functions);
-    }
-};
+    RegisterHandlers(functions);
+}
 
-class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
-public:
-    explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {0, nullptr, "ListApplicationRecord"},
-            {1, nullptr, "GenerateApplicationRecordCount"},
-            {2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
-            {3, nullptr, "GetApplicationViewDeprecated"},
-            {4, nullptr, "DeleteApplicationEntity"},
-            {5, nullptr, "DeleteApplicationCompletely"},
-            {6, nullptr, "IsAnyApplicationEntityRedundant"},
-            {7, nullptr, "DeleteRedundantApplicationEntity"},
-            {8, nullptr, "IsApplicationEntityMovable"},
-            {9, nullptr, "MoveApplicationEntity"},
-            {11, nullptr, "CalculateApplicationOccupiedSize"},
-            {16, nullptr, "PushApplicationRecord"},
-            {17, nullptr, "ListApplicationRecordContentMeta"},
-            {19, nullptr, "LaunchApplicationOld"},
-            {21, nullptr, "GetApplicationContentPath"},
-            {22, nullptr, "TerminateApplication"},
-            {23, nullptr, "ResolveApplicationContentPath"},
-            {26, nullptr, "BeginInstallApplication"},
-            {27, nullptr, "DeleteApplicationRecord"},
-            {30, nullptr, "RequestApplicationUpdateInfo"},
-            {32, nullptr, "CancelApplicationDownload"},
-            {33, nullptr, "ResumeApplicationDownload"},
-            {35, nullptr, "UpdateVersionList"},
-            {36, nullptr, "PushLaunchVersion"},
-            {37, nullptr, "ListRequiredVersion"},
-            {38, nullptr, "CheckApplicationLaunchVersion"},
-            {39, nullptr, "CheckApplicationLaunchRights"},
-            {40, nullptr, "GetApplicationLogoData"},
-            {41, nullptr, "CalculateApplicationDownloadRequiredSize"},
-            {42, nullptr, "CleanupSdCard"},
-            {43, nullptr, "CheckSdCardMountStatus"},
-            {44, nullptr, "GetSdCardMountStatusChangedEvent"},
-            {45, nullptr, "GetGameCardAttachmentEvent"},
-            {46, nullptr, "GetGameCardAttachmentInfo"},
-            {47, nullptr, "GetTotalSpaceSize"},
-            {48, nullptr, "GetFreeSpaceSize"},
-            {49, nullptr, "GetSdCardRemovedEvent"},
-            {52, nullptr, "GetGameCardUpdateDetectionEvent"},
-            {53, nullptr, "DisableApplicationAutoDelete"},
-            {54, nullptr, "EnableApplicationAutoDelete"},
-            {55, nullptr, "GetApplicationDesiredLanguage"},
-            {56, nullptr, "SetApplicationTerminateResult"},
-            {57, nullptr, "ClearApplicationTerminateResult"},
-            {58, nullptr, "GetLastSdCardMountUnexpectedResult"},
-            {59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
-            {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
-            {61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
-            {62, nullptr, "GetGameCardStopper"},
-            {63, nullptr, "IsSystemProgramInstalled"},
-            {64, nullptr, "StartApplyDeltaTask"},
-            {65, nullptr, "GetRequestServerStopper"},
-            {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
-            {67, nullptr, "CancelApplicationApplyDelta"},
-            {68, nullptr, "ResumeApplicationApplyDelta"},
-            {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
-            {70, nullptr, "ResumeAll"},
-            {71, nullptr, "GetStorageSize"},
-            {80, nullptr, "RequestDownloadApplication"},
-            {81, nullptr, "RequestDownloadAddOnContent"},
-            {82, nullptr, "DownloadApplication"},
-            {83, nullptr, "CheckApplicationResumeRights"},
-            {84, nullptr, "GetDynamicCommitEvent"},
-            {85, nullptr, "RequestUpdateApplication2"},
-            {86, nullptr, "EnableApplicationCrashReport"},
-            {87, nullptr, "IsApplicationCrashReportEnabled"},
-            {90, nullptr, "BoostSystemMemoryResourceLimit"},
-            {91, nullptr, "DeprecatedLaunchApplication"},
-            {92, nullptr, "GetRunningApplicationProgramId"},
-            {93, nullptr, "GetMainApplicationProgramIndex"},
-            {94, nullptr, "LaunchApplication"},
-            {95, nullptr, "GetApplicationLaunchInfo"},
-            {96, nullptr, "AcquireApplicationLaunchInfo"},
-            {97, nullptr, "GetMainApplicationProgramIndex2"},
-            {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
-            {100, nullptr, "ResetToFactorySettings"},
-            {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
-            {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
-            {200, nullptr, "CalculateUserSaveDataStatistics"},
-            {201, nullptr, "DeleteUserSaveDataAll"},
-            {210, nullptr, "DeleteUserSystemSaveData"},
-            {211, nullptr, "DeleteSaveData"},
-            {220, nullptr, "UnregisterNetworkServiceAccount"},
-            {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
-            {300, nullptr, "GetApplicationShellEvent"},
-            {301, nullptr, "PopApplicationShellEventInfo"},
-            {302, nullptr, "LaunchLibraryApplet"},
-            {303, nullptr, "TerminateLibraryApplet"},
-            {304, nullptr, "LaunchSystemApplet"},
-            {305, nullptr, "TerminateSystemApplet"},
-            {306, nullptr, "LaunchOverlayApplet"},
-            {307, nullptr, "TerminateOverlayApplet"},
-            {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"},
-            {401, nullptr, "InvalidateAllApplicationControlCache"},
-            {402, nullptr, "RequestDownloadApplicationControlData"},
-            {403, nullptr, "GetMaxApplicationControlCacheCount"},
-            {404, nullptr, "InvalidateApplicationControlCache"},
-            {405, nullptr, "ListApplicationControlCacheEntryInfo"},
-            {406, nullptr, "GetApplicationControlProperty"},
-            {502, nullptr, "RequestCheckGameCardRegistration"},
-            {503, nullptr, "RequestGameCardRegistrationGoldPoint"},
-            {504, nullptr, "RequestRegisterGameCard"},
-            {505, nullptr, "GetGameCardMountFailureEvent"},
-            {506, nullptr, "IsGameCardInserted"},
-            {507, nullptr, "EnsureGameCardAccess"},
-            {508, nullptr, "GetLastGameCardMountFailureResult"},
-            {509, nullptr, "ListApplicationIdOnGameCard"},
-            {600, nullptr, "CountApplicationContentMeta"},
-            {601, nullptr, "ListApplicationContentMetaStatus"},
-            {602, nullptr, "ListAvailableAddOnContent"},
-            {603, nullptr, "GetOwnedApplicationContentMetaStatus"},
-            {604, nullptr, "RegisterContentsExternalKey"},
-            {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
-            {606, nullptr, "GetContentMetaStorage"},
-            {607, nullptr, "ListAvailableAddOnContent"},
-            {700, nullptr, "PushDownloadTaskList"},
-            {701, nullptr, "ClearTaskStatusList"},
-            {702, nullptr, "RequestDownloadTaskList"},
-            {703, nullptr, "RequestEnsureDownloadTask"},
-            {704, nullptr, "ListDownloadTaskStatus"},
-            {705, nullptr, "RequestDownloadTaskListData"},
-            {800, nullptr, "RequestVersionList"},
-            {801, nullptr, "ListVersionList"},
-            {802, nullptr, "RequestVersionListData"},
-            {900, nullptr, "GetApplicationRecord"},
-            {901, nullptr, "GetApplicationRecordProperty"},
-            {902, nullptr, "EnableApplicationAutoUpdate"},
-            {903, nullptr, "DisableApplicationAutoUpdate"},
-            {904, nullptr, "TouchApplication"},
-            {905, nullptr, "RequestApplicationUpdate"},
-            {906, nullptr, "IsApplicationUpdateRequested"},
-            {907, nullptr, "WithdrawApplicationUpdateRequest"},
-            {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
-            {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
-            {910, nullptr, "HasApplicationRecord"},
-            {911, nullptr, "SetPreInstalledApplication"},
-            {912, nullptr, "ClearPreInstalledApplicationFlag"},
-            {1000, nullptr, "RequestVerifyApplicationDeprecated"},
-            {1001, nullptr, "CorruptApplicationForDebug"},
-            {1002, nullptr, "RequestVerifyAddOnContentsRights"},
-            {1003, nullptr, "RequestVerifyApplication"},
-            {1004, nullptr, "CorruptContentForDebug"},
-            {1200, nullptr, "NeedsUpdateVulnerability"},
-            {1300, nullptr, "IsAnyApplicationEntityInstalled"},
-            {1301, nullptr, "DeleteApplicationContentEntities"},
-            {1302, nullptr, "CleanupUnrecordedApplicationEntity"},
-            {1303, nullptr, "CleanupAddOnContentsWithNoRights"},
-            {1304, nullptr, "DeleteApplicationContentEntity"},
-            {1305, nullptr, "TryDeleteRunningApplicationEntity"},
-            {1306, nullptr, "TryDeleteRunningApplicationCompletely"},
-            {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
-            {1308, nullptr, "DeleteApplicationCompletelyForDebug"},
-            {1309, nullptr, "CleanupUnavailableAddOnContents"},
-            {1400, nullptr, "PrepareShutdown"},
-            {1500, nullptr, "FormatSdCard"},
-            {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
-            {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
-            {1504, nullptr, "InsertSdCard"},
-            {1505, nullptr, "RemoveSdCard"},
-            {1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
-            {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
-            {1700, nullptr, "ListApplicationDownloadingContentMeta"},
-            {1701, nullptr, "GetApplicationView"},
-            {1702, nullptr, "GetApplicationDownloadTaskStatus"},
-            {1703, nullptr, "GetApplicationViewDownloadErrorContext"},
-            {1800, nullptr, "IsNotificationSetupCompleted"},
-            {1801, nullptr, "GetLastNotificationInfoCount"},
-            {1802, nullptr, "ListLastNotificationInfo"},
-            {1803, nullptr, "ListNotificationTask"},
-            {1900, nullptr, "IsActiveAccount"},
-            {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
-            {1902, nullptr, "GetApplicationTicketInfo"},
-            {2000, nullptr, "GetSystemDeliveryInfo"},
-            {2001, nullptr, "SelectLatestSystemDeliveryInfo"},
-            {2002, nullptr, "VerifyDeliveryProtocolVersion"},
-            {2003, nullptr, "GetApplicationDeliveryInfo"},
-            {2004, nullptr, "HasAllContentsToDeliver"},
-            {2005, nullptr, "CompareApplicationDeliveryInfo"},
-            {2006, nullptr, "CanDeliverApplication"},
-            {2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
-            {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
-            {2009, nullptr, "EstimateRequiredSize"},
-            {2010, nullptr, "RequestReceiveApplication"},
-            {2011, nullptr, "CommitReceiveApplication"},
-            {2012, nullptr, "GetReceiveApplicationProgress"},
-            {2013, nullptr, "RequestSendApplication"},
-            {2014, nullptr, "GetSendApplicationProgress"},
-            {2015, nullptr, "CompareSystemDeliveryInfo"},
-            {2016, nullptr, "ListNotCommittedContentMeta"},
-            {2017, nullptr, "CreateDownloadTask"},
-            {2018, nullptr, "GetApplicationDeliveryInfoHash"},
-            {2050, nullptr, "GetApplicationRightsOnClient"},
-            {2100, nullptr, "GetApplicationTerminateResult"},
-            {2101, nullptr, "GetRawApplicationTerminateResult"},
-            {2150, nullptr, "CreateRightsEnvironment"},
-            {2151, nullptr, "DestroyRightsEnvironment"},
-            {2152, nullptr, "ActivateRightsEnvironment"},
-            {2153, nullptr, "DeactivateRightsEnvironment"},
-            {2154, nullptr, "ForceActivateRightsContextForExit"},
-            {2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
-            {2161, nullptr, "SetUsersToRightsEnvironment"},
-            {2170, nullptr, "GetRightsEnvironmentStatus"},
-            {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
-            {2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
-            {2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"},
-            {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
-            {2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
-            {2199, nullptr, "GetRightsEnvironmentCountForDebug"},
-            {2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
-            {2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
-            {2250, nullptr, "RequestReportActiveELicence"},
-            {2300, nullptr, "ListEventLog"},
-        };
-        // clang-format on
+IAccountProxyInterface::~IAccountProxyInterface() = default;
 
-        RegisterHandlers(functions);
-    }
+IApplicationManagerInterface::IApplicationManagerInterface()
+    : ServiceFramework{"IApplicationManagerInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "ListApplicationRecord"},
+        {1, nullptr, "GenerateApplicationRecordCount"},
+        {2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
+        {3, nullptr, "GetApplicationViewDeprecated"},
+        {4, nullptr, "DeleteApplicationEntity"},
+        {5, nullptr, "DeleteApplicationCompletely"},
+        {6, nullptr, "IsAnyApplicationEntityRedundant"},
+        {7, nullptr, "DeleteRedundantApplicationEntity"},
+        {8, nullptr, "IsApplicationEntityMovable"},
+        {9, nullptr, "MoveApplicationEntity"},
+        {11, nullptr, "CalculateApplicationOccupiedSize"},
+        {16, nullptr, "PushApplicationRecord"},
+        {17, nullptr, "ListApplicationRecordContentMeta"},
+        {19, nullptr, "LaunchApplicationOld"},
+        {21, nullptr, "GetApplicationContentPath"},
+        {22, nullptr, "TerminateApplication"},
+        {23, nullptr, "ResolveApplicationContentPath"},
+        {26, nullptr, "BeginInstallApplication"},
+        {27, nullptr, "DeleteApplicationRecord"},
+        {30, nullptr, "RequestApplicationUpdateInfo"},
+        {32, nullptr, "CancelApplicationDownload"},
+        {33, nullptr, "ResumeApplicationDownload"},
+        {35, nullptr, "UpdateVersionList"},
+        {36, nullptr, "PushLaunchVersion"},
+        {37, nullptr, "ListRequiredVersion"},
+        {38, nullptr, "CheckApplicationLaunchVersion"},
+        {39, nullptr, "CheckApplicationLaunchRights"},
+        {40, nullptr, "GetApplicationLogoData"},
+        {41, nullptr, "CalculateApplicationDownloadRequiredSize"},
+        {42, nullptr, "CleanupSdCard"},
+        {43, nullptr, "CheckSdCardMountStatus"},
+        {44, nullptr, "GetSdCardMountStatusChangedEvent"},
+        {45, nullptr, "GetGameCardAttachmentEvent"},
+        {46, nullptr, "GetGameCardAttachmentInfo"},
+        {47, nullptr, "GetTotalSpaceSize"},
+        {48, nullptr, "GetFreeSpaceSize"},
+        {49, nullptr, "GetSdCardRemovedEvent"},
+        {52, nullptr, "GetGameCardUpdateDetectionEvent"},
+        {53, nullptr, "DisableApplicationAutoDelete"},
+        {54, nullptr, "EnableApplicationAutoDelete"},
+        {55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
+        {56, nullptr, "SetApplicationTerminateResult"},
+        {57, nullptr, "ClearApplicationTerminateResult"},
+        {58, nullptr, "GetLastSdCardMountUnexpectedResult"},
+        {59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"},
+        {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
+        {61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
+        {62, nullptr, "GetGameCardStopper"},
+        {63, nullptr, "IsSystemProgramInstalled"},
+        {64, nullptr, "StartApplyDeltaTask"},
+        {65, nullptr, "GetRequestServerStopper"},
+        {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
+        {67, nullptr, "CancelApplicationApplyDelta"},
+        {68, nullptr, "ResumeApplicationApplyDelta"},
+        {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
+        {70, nullptr, "ResumeAll"},
+        {71, nullptr, "GetStorageSize"},
+        {80, nullptr, "RequestDownloadApplication"},
+        {81, nullptr, "RequestDownloadAddOnContent"},
+        {82, nullptr, "DownloadApplication"},
+        {83, nullptr, "CheckApplicationResumeRights"},
+        {84, nullptr, "GetDynamicCommitEvent"},
+        {85, nullptr, "RequestUpdateApplication2"},
+        {86, nullptr, "EnableApplicationCrashReport"},
+        {87, nullptr, "IsApplicationCrashReportEnabled"},
+        {90, nullptr, "BoostSystemMemoryResourceLimit"},
+        {91, nullptr, "DeprecatedLaunchApplication"},
+        {92, nullptr, "GetRunningApplicationProgramId"},
+        {93, nullptr, "GetMainApplicationProgramIndex"},
+        {94, nullptr, "LaunchApplication"},
+        {95, nullptr, "GetApplicationLaunchInfo"},
+        {96, nullptr, "AcquireApplicationLaunchInfo"},
+        {97, nullptr, "GetMainApplicationProgramIndex2"},
+        {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
+        {100, nullptr, "ResetToFactorySettings"},
+        {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
+        {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
+        {200, nullptr, "CalculateUserSaveDataStatistics"},
+        {201, nullptr, "DeleteUserSaveDataAll"},
+        {210, nullptr, "DeleteUserSystemSaveData"},
+        {211, nullptr, "DeleteSaveData"},
+        {220, nullptr, "UnregisterNetworkServiceAccount"},
+        {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
+        {300, nullptr, "GetApplicationShellEvent"},
+        {301, nullptr, "PopApplicationShellEventInfo"},
+        {302, nullptr, "LaunchLibraryApplet"},
+        {303, nullptr, "TerminateLibraryApplet"},
+        {304, nullptr, "LaunchSystemApplet"},
+        {305, nullptr, "TerminateSystemApplet"},
+        {306, nullptr, "LaunchOverlayApplet"},
+        {307, nullptr, "TerminateOverlayApplet"},
+        {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"},
+        {401, nullptr, "InvalidateAllApplicationControlCache"},
+        {402, nullptr, "RequestDownloadApplicationControlData"},
+        {403, nullptr, "GetMaxApplicationControlCacheCount"},
+        {404, nullptr, "InvalidateApplicationControlCache"},
+        {405, nullptr, "ListApplicationControlCacheEntryInfo"},
+        {406, nullptr, "GetApplicationControlProperty"},
+        {502, nullptr, "RequestCheckGameCardRegistration"},
+        {503, nullptr, "RequestGameCardRegistrationGoldPoint"},
+        {504, nullptr, "RequestRegisterGameCard"},
+        {505, nullptr, "GetGameCardMountFailureEvent"},
+        {506, nullptr, "IsGameCardInserted"},
+        {507, nullptr, "EnsureGameCardAccess"},
+        {508, nullptr, "GetLastGameCardMountFailureResult"},
+        {509, nullptr, "ListApplicationIdOnGameCard"},
+        {600, nullptr, "CountApplicationContentMeta"},
+        {601, nullptr, "ListApplicationContentMetaStatus"},
+        {602, nullptr, "ListAvailableAddOnContent"},
+        {603, nullptr, "GetOwnedApplicationContentMetaStatus"},
+        {604, nullptr, "RegisterContentsExternalKey"},
+        {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
+        {606, nullptr, "GetContentMetaStorage"},
+        {607, nullptr, "ListAvailableAddOnContent"},
+        {700, nullptr, "PushDownloadTaskList"},
+        {701, nullptr, "ClearTaskStatusList"},
+        {702, nullptr, "RequestDownloadTaskList"},
+        {703, nullptr, "RequestEnsureDownloadTask"},
+        {704, nullptr, "ListDownloadTaskStatus"},
+        {705, nullptr, "RequestDownloadTaskListData"},
+        {800, nullptr, "RequestVersionList"},
+        {801, nullptr, "ListVersionList"},
+        {802, nullptr, "RequestVersionListData"},
+        {900, nullptr, "GetApplicationRecord"},
+        {901, nullptr, "GetApplicationRecordProperty"},
+        {902, nullptr, "EnableApplicationAutoUpdate"},
+        {903, nullptr, "DisableApplicationAutoUpdate"},
+        {904, nullptr, "TouchApplication"},
+        {905, nullptr, "RequestApplicationUpdate"},
+        {906, nullptr, "IsApplicationUpdateRequested"},
+        {907, nullptr, "WithdrawApplicationUpdateRequest"},
+        {908, nullptr, "ListApplicationRecordInstalledContentMeta"},
+        {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
+        {910, nullptr, "HasApplicationRecord"},
+        {911, nullptr, "SetPreInstalledApplication"},
+        {912, nullptr, "ClearPreInstalledApplicationFlag"},
+        {1000, nullptr, "RequestVerifyApplicationDeprecated"},
+        {1001, nullptr, "CorruptApplicationForDebug"},
+        {1002, nullptr, "RequestVerifyAddOnContentsRights"},
+        {1003, nullptr, "RequestVerifyApplication"},
+        {1004, nullptr, "CorruptContentForDebug"},
+        {1200, nullptr, "NeedsUpdateVulnerability"},
+        {1300, nullptr, "IsAnyApplicationEntityInstalled"},
+        {1301, nullptr, "DeleteApplicationContentEntities"},
+        {1302, nullptr, "CleanupUnrecordedApplicationEntity"},
+        {1303, nullptr, "CleanupAddOnContentsWithNoRights"},
+        {1304, nullptr, "DeleteApplicationContentEntity"},
+        {1305, nullptr, "TryDeleteRunningApplicationEntity"},
+        {1306, nullptr, "TryDeleteRunningApplicationCompletely"},
+        {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
+        {1308, nullptr, "DeleteApplicationCompletelyForDebug"},
+        {1309, nullptr, "CleanupUnavailableAddOnContents"},
+        {1400, nullptr, "PrepareShutdown"},
+        {1500, nullptr, "FormatSdCard"},
+        {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
+        {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
+        {1504, nullptr, "InsertSdCard"},
+        {1505, nullptr, "RemoveSdCard"},
+        {1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
+        {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
+        {1700, nullptr, "ListApplicationDownloadingContentMeta"},
+        {1701, nullptr, "GetApplicationView"},
+        {1702, nullptr, "GetApplicationDownloadTaskStatus"},
+        {1703, nullptr, "GetApplicationViewDownloadErrorContext"},
+        {1800, nullptr, "IsNotificationSetupCompleted"},
+        {1801, nullptr, "GetLastNotificationInfoCount"},
+        {1802, nullptr, "ListLastNotificationInfo"},
+        {1803, nullptr, "ListNotificationTask"},
+        {1900, nullptr, "IsActiveAccount"},
+        {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
+        {1902, nullptr, "GetApplicationTicketInfo"},
+        {2000, nullptr, "GetSystemDeliveryInfo"},
+        {2001, nullptr, "SelectLatestSystemDeliveryInfo"},
+        {2002, nullptr, "VerifyDeliveryProtocolVersion"},
+        {2003, nullptr, "GetApplicationDeliveryInfo"},
+        {2004, nullptr, "HasAllContentsToDeliver"},
+        {2005, nullptr, "CompareApplicationDeliveryInfo"},
+        {2006, nullptr, "CanDeliverApplication"},
+        {2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
+        {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
+        {2009, nullptr, "EstimateRequiredSize"},
+        {2010, nullptr, "RequestReceiveApplication"},
+        {2011, nullptr, "CommitReceiveApplication"},
+        {2012, nullptr, "GetReceiveApplicationProgress"},
+        {2013, nullptr, "RequestSendApplication"},
+        {2014, nullptr, "GetSendApplicationProgress"},
+        {2015, nullptr, "CompareSystemDeliveryInfo"},
+        {2016, nullptr, "ListNotCommittedContentMeta"},
+        {2017, nullptr, "CreateDownloadTask"},
+        {2018, nullptr, "GetApplicationDeliveryInfoHash"},
+        {2050, nullptr, "GetApplicationRightsOnClient"},
+        {2100, nullptr, "GetApplicationTerminateResult"},
+        {2101, nullptr, "GetRawApplicationTerminateResult"},
+        {2150, nullptr, "CreateRightsEnvironment"},
+        {2151, nullptr, "DestroyRightsEnvironment"},
+        {2152, nullptr, "ActivateRightsEnvironment"},
+        {2153, nullptr, "DeactivateRightsEnvironment"},
+        {2154, nullptr, "ForceActivateRightsContextForExit"},
+        {2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
+        {2161, nullptr, "SetUsersToRightsEnvironment"},
+        {2170, nullptr, "GetRightsEnvironmentStatus"},
+        {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
+        {2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
+        {2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"},
+        {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
+        {2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
+        {2199, nullptr, "GetRightsEnvironmentCountForDebug"},
+        {2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
+        {2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
+        {2250, nullptr, "RequestReportActiveELicence"},
+        {2300, nullptr, "ListEventLog"},
+    };
+    // clang-format on
 
-    void GetApplicationControlData(Kernel::HLERequestContext& ctx) {
-        IPC::RequestParser rp{ctx};
-        const auto flag = rp.PopRaw<u64>();
-        LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
+    RegisterHandlers(functions);
+}
 
-        const auto title_id = rp.PopRaw<u64>();
+IApplicationManagerInterface::~IApplicationManagerInterface() = default;
 
-        const auto size = ctx.GetWriteBufferSize();
+void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto flag = rp.PopRaw<u64>();
+    LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
 
-        const FileSys::PatchManager pm{title_id};
-        const auto control = pm.GetControlMetadata();
+    const auto title_id = rp.PopRaw<u64>();
 
-        std::vector<u8> out;
+    const auto size = ctx.GetWriteBufferSize();
 
-        if (control.first != nullptr) {
-            if (size < 0x4000) {
-                LOG_ERROR(Service_NS,
-                          "output buffer is too small! (actual={:016X}, expected_min=0x4000)",
-                          size);
-                IPC::ResponseBuilder rb{ctx, 2};
-                // TODO(DarkLordZach): Find a better error code for this.
-                rb.Push(ResultCode(-1));
-                return;
-            }
+    const FileSys::PatchManager pm{title_id};
+    const auto control = pm.GetControlMetadata();
 
-            out.resize(0x4000);
-            const auto bytes = control.first->GetRawBytes();
-            std::memcpy(out.data(), bytes.data(), bytes.size());
-        } else {
-            LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.",
-                        title_id);
-            out.resize(std::min<u64>(0x4000, size));
+    std::vector<u8> out;
+
+    if (control.first != nullptr) {
+        if (size < 0x4000) {
+            LOG_ERROR(Service_NS,
+                      "output buffer is too small! (actual={:016X}, expected_min=0x4000)", size);
+            IPC::ResponseBuilder rb{ctx, 2};
+            // TODO(DarkLordZach): Find a better error code for this.
+            rb.Push(ResultCode(-1));
+            return;
         }
 
-        if (control.second != nullptr) {
-            if (size < 0x4000 + control.second->GetSize()) {
-                LOG_ERROR(Service_NS,
-                          "output buffer is too small! (actual={:016X}, expected_min={:016X})",
-                          size, 0x4000 + control.second->GetSize());
-                IPC::ResponseBuilder rb{ctx, 2};
-                // TODO(DarkLordZach): Find a better error code for this.
-                rb.Push(ResultCode(-1));
-                return;
-            }
+        out.resize(0x4000);
+        const auto bytes = control.first->GetRawBytes();
+        std::memcpy(out.data(), bytes.data(), bytes.size());
+    } else {
+        LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.",
+                    title_id);
+        out.resize(std::min<u64>(0x4000, size));
+    }
 
-            out.resize(0x4000 + control.second->GetSize());
-            control.second->Read(out.data() + 0x4000, control.second->GetSize());
-        } else {
-            LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.",
-                        title_id);
+    if (control.second != nullptr) {
+        if (size < 0x4000 + control.second->GetSize()) {
+            LOG_ERROR(Service_NS,
+                      "output buffer is too small! (actual={:016X}, expected_min={:016X})", size,
+                      0x4000 + control.second->GetSize());
+            IPC::ResponseBuilder rb{ctx, 2};
+            // TODO(DarkLordZach): Find a better error code for this.
+            rb.Push(ResultCode(-1));
+            return;
         }
 
-        ctx.WriteBuffer(out);
+        out.resize(0x4000 + control.second->GetSize());
+        control.second->Read(out.data() + 0x4000, control.second->GetSize());
+    } else {
+        LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.",
+                    title_id);
+    }
 
+    ctx.WriteBuffer(out);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(RESULT_SUCCESS);
+    rb.Push<u32>(static_cast<u32>(out.size()));
+}
+
+void IApplicationManagerInterface::GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto supported_languages = rp.Pop<u32>();
+
+    const auto res = GetApplicationDesiredLanguage(supported_languages);
+    if (res.Succeeded()) {
         IPC::ResponseBuilder rb{ctx, 3};
         rb.Push(RESULT_SUCCESS);
-        rb.Push<u32>(static_cast<u32>(out.size()));
+        rb.Push<u32>(*res);
+    } else {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(res.Code());
     }
-};
+}
 
-class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
-public:
-    explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {0, nullptr, "GetLaunchRequiredVersion"},
-            {1, nullptr, "UpgradeLaunchRequiredVersion"},
-            {35, nullptr, "UpdateVersionList"},
-            {36, nullptr, "PushLaunchVersion"},
-            {37, nullptr, "ListRequiredVersion"},
-            {800, nullptr, "RequestVersionList"},
-            {801, nullptr, "ListVersionList"},
-            {802, nullptr, "RequestVersionListData"},
-            {1000, nullptr, "PerformAutoUpdate"},
-        };
-        // clang-format on
+ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
+    const u32 supported_languages) {
+    LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages);
 
-        RegisterHandlers(functions);
+    // Get language code from settings
+    const auto language_code = Set::GetLanguageCodeFromIndex(Settings::values.language_index);
+
+    // Convert to application language, get priority list
+    const auto application_language = ConvertToApplicationLanguage(language_code);
+    if (application_language == std::nullopt) {
+        return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
     }
-};
-
-class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
-public:
-    explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {11, nullptr, "CalculateApplicationOccupiedSize"},
-            {43, nullptr, "CheckSdCardMountStatus"},
-            {47, nullptr, "GetTotalSpaceSize"},
-            {48, nullptr, "GetFreeSpaceSize"},
-            {600, nullptr, "CountApplicationContentMeta"},
-            {601, nullptr, "ListApplicationContentMetaStatus"},
-            {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
-            {607, nullptr, "IsAnyApplicationRunning"},
-        };
-        // clang-format on
-
-        RegisterHandlers(functions);
+    const auto priority_list = GetApplicationLanguagePriorityList(*application_language);
+    if (!priority_list) {
+        return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
     }
-};
 
-class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
-public:
-    explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {21, nullptr, "GetApplicationContentPath"},
-            {23, nullptr, "ResolveApplicationContentPath"},
-            {93, nullptr, "GetRunningApplicationProgramId"},
-        };
-        // clang-format on
-
-        RegisterHandlers(functions);
+    // Try to find a valid language.
+    for (const auto lang : *priority_list) {
+        const auto supported_flag = GetSupportedLanguageFlag(lang);
+        if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) {
+            return MakeResult(static_cast<u8>(lang));
+        }
     }
-};
 
-class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
-public:
-    explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {701, nullptr, "ClearTaskStatusList"},
-            {702, nullptr, "RequestDownloadTaskList"},
-            {703, nullptr, "RequestEnsureDownloadTask"},
-            {704, nullptr, "ListDownloadTaskStatus"},
-            {705, nullptr, "RequestDownloadTaskListData"},
-            {706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
-            {707, nullptr, "EnableAutoCommit"},
-            {708, nullptr, "DisableAutoCommit"},
-            {709, nullptr, "TriggerDynamicCommitEvent"},
-        };
-        // clang-format on
+    return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
+}
 
-        RegisterHandlers(functions);
+void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
+    Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto application_language = rp.Pop<u8>();
+
+    const auto res = ConvertApplicationLanguageToLanguageCode(application_language);
+    if (res.Succeeded()) {
+        IPC::ResponseBuilder rb{ctx, 4};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push(*res);
+    } else {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(res.Code());
     }
-};
+}
 
-class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
-public:
-    explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {0, nullptr, "RequestLinkDevice"},
-            {1, nullptr, "RequestCleanupAllPreInstalledApplications"},
-            {2, nullptr, "RequestCleanupPreInstalledApplication"},
-            {3, nullptr, "RequestSyncRights"},
-            {4, nullptr, "RequestUnlinkDevice"},
-            {5, nullptr, "RequestRevokeAllELicense"},
-        };
-        // clang-format on
-
-        RegisterHandlers(functions);
+ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
+    u8 application_language) {
+    const auto language_code =
+        ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
+    if (language_code == std::nullopt) {
+        return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
     }
-};
 
-class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
-public:
-    explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} {
-        // clang-format off
+    return MakeResult(static_cast<u64>(*language_code));
+}
+
+IApplicationVersionInterface::IApplicationVersionInterface()
+    : ServiceFramework{"IApplicationVersionInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "GetLaunchRequiredVersion"},
+        {1, nullptr, "UpgradeLaunchRequiredVersion"},
+        {35, nullptr, "UpdateVersionList"},
+        {36, nullptr, "PushLaunchVersion"},
+        {37, nullptr, "ListRequiredVersion"},
+        {800, nullptr, "RequestVersionList"},
+        {801, nullptr, "ListVersionList"},
+        {802, nullptr, "RequestVersionListData"},
+        {1000, nullptr, "PerformAutoUpdate"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IApplicationVersionInterface::~IApplicationVersionInterface() = default;
+
+IContentManagerInterface::IContentManagerInterface()
+    : ServiceFramework{"IContentManagerInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {11, nullptr, "CalculateApplicationOccupiedSize"},
+        {43, nullptr, "CheckSdCardMountStatus"},
+        {47, nullptr, "GetTotalSpaceSize"},
+        {48, nullptr, "GetFreeSpaceSize"},
+        {600, nullptr, "CountApplicationContentMeta"},
+        {601, nullptr, "ListApplicationContentMetaStatus"},
+        {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
+        {607, nullptr, "IsAnyApplicationRunning"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IContentManagerInterface::~IContentManagerInterface() = default;
+
+IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {21, nullptr, "GetApplicationContentPath"},
+        {23, nullptr, "ResolveApplicationContentPath"},
+        {93, nullptr, "GetRunningApplicationProgramId"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IDocumentInterface::~IDocumentInterface() = default;
+
+IDownloadTaskInterface::IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {701, nullptr, "ClearTaskStatusList"},
+        {702, nullptr, "RequestDownloadTaskList"},
+        {703, nullptr, "RequestEnsureDownloadTask"},
+        {704, nullptr, "ListDownloadTaskStatus"},
+        {705, nullptr, "RequestDownloadTaskListData"},
+        {706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
+        {707, nullptr, "EnableAutoCommit"},
+        {708, nullptr, "DisableAutoCommit"},
+        {709, nullptr, "TriggerDynamicCommitEvent"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IDownloadTaskInterface::~IDownloadTaskInterface() = default;
+
+IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "RequestLinkDevice"},
+        {1, nullptr, "RequestCleanupAllPreInstalledApplications"},
+        {2, nullptr, "RequestCleanupPreInstalledApplication"},
+        {3, nullptr, "RequestSyncRights"},
+        {4, nullptr, "RequestUnlinkDevice"},
+        {5, nullptr, "RequestRevokeAllELicense"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IECommerceInterface::~IECommerceInterface() = default;
+
+IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface()
+    : ServiceFramework{"IFactoryResetInterface"} {
+    // clang-format off
         static const FunctionInfo functions[] = {
             {100, nullptr, "ResetToFactorySettings"},
             {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
             {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
         };
-        // clang-format on
+    // clang-format on
 
-        RegisterHandlers(functions);
-    }
-};
+    RegisterHandlers(functions);
+}
 
-class NS final : public ServiceFramework<NS> {
-public:
-    explicit NS(const char* name) : ServiceFramework{name} {
-        // clang-format off
-        static const FunctionInfo functions[] = {
-            {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
-            {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
-            {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
-            {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
-            {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
-            {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
-            {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
-            {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
-        };
-        // clang-format on
+IFactoryResetInterface::~IFactoryResetInterface() = default;
 
-        RegisterHandlers(functions);
-    }
+NS::NS(const char* name) : ServiceFramework{name} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
+        {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
+        {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
+        {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
+        {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
+        {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
+        {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
+        {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
+    };
+    // clang-format on
 
-private:
-    template <typename T>
-    void PushInterface(Kernel::HLERequestContext& ctx) {
-        LOG_DEBUG(Service_NS, "called");
+    RegisterHandlers(functions);
+}
 
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(RESULT_SUCCESS);
-        rb.PushIpcInterface<T>();
-    }
-};
+NS::~NS() = default;
+
+std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
+    return GetInterface<IApplicationManagerInterface>();
+}
 
 class NS_DEV final : public ServiceFramework<NS_DEV> {
 public:
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index b81ca8f1e..0f4bab4cb 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -8,6 +8,88 @@
 
 namespace Service::NS {
 
+class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
+public:
+    explicit IAccountProxyInterface();
+    ~IAccountProxyInterface();
+};
+
+class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
+public:
+    explicit IApplicationManagerInterface();
+    ~IApplicationManagerInterface();
+
+    ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages);
+    ResultVal<u64> ConvertApplicationLanguageToLanguageCode(u8 application_language);
+
+private:
+    void GetApplicationControlData(Kernel::HLERequestContext& ctx);
+    void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx);
+    void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx);
+};
+
+class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
+public:
+    explicit IApplicationVersionInterface();
+    ~IApplicationVersionInterface();
+};
+
+class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
+public:
+    explicit IContentManagerInterface();
+    ~IContentManagerInterface();
+};
+
+class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
+public:
+    explicit IDocumentInterface();
+    ~IDocumentInterface();
+};
+
+class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
+public:
+    explicit IDownloadTaskInterface();
+    ~IDownloadTaskInterface();
+};
+
+class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
+public:
+    explicit IECommerceInterface();
+    ~IECommerceInterface();
+};
+
+class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
+public:
+    explicit IFactoryResetInterface();
+    ~IFactoryResetInterface();
+};
+
+class NS final : public ServiceFramework<NS> {
+public:
+    explicit NS(const char* name);
+    ~NS();
+
+    std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
+
+private:
+    template <typename T>
+    void PushInterface(Kernel::HLERequestContext& ctx) {
+        LOG_DEBUG(Service_NS, "called");
+
+        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+        rb.Push(RESULT_SUCCESS);
+        rb.PushIpcInterface<T>();
+    }
+
+    template <typename T>
+    std::shared_ptr<T> GetInterface() const {
+        static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>,
+                      "Not a base of ServiceFrameworkBase");
+
+        return std::make_shared<T>();
+    }
+};
+
 /// Registers all NS services with the specified service manager.
 void InstallInterfaces(SM::ServiceManager& service_manager);
 
diff --git a/src/core/hle/service/ns/ns_language.h b/src/core/hle/service/ns/ns_language.h
new file mode 100644
index 000000000..59ac85a19
--- /dev/null
+++ b/src/core/hle/service/ns/ns_language.h
@@ -0,0 +1,42 @@
+// Copyright 2019 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+#include <optional>
+#include <string>
+#include "common/common_types.h"
+#include "core/hle/service/set/set.h"
+
+namespace Service::NS {
+/// This is nn::ns::detail::ApplicationLanguage
+enum class ApplicationLanguage : u8 {
+    AmericanEnglish = 0,
+    BritishEnglish,
+    Japanese,
+    French,
+    German,
+    LatinAmericanSpanish,
+    Spanish,
+    Italian,
+    Dutch,
+    CanadianFrench,
+    Portuguese,
+    Russian,
+    Korean,
+    TraditionalChinese,
+    SimplifiedChinese,
+    Count
+};
+using ApplicationLanguagePriorityList =
+    const std::array<ApplicationLanguage, static_cast<std::size_t>(ApplicationLanguage::Count)>;
+
+constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
+    return 1U << static_cast<u32>(lang);
+}
+
+const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
+std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
+    Service::Set::LanguageCode language_code);
+std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
+} // namespace Service::NS
\ No newline at end of file