Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 91311)
+++ /trunk/Config.kmk	(revision 91312)
@@ -276,4 +276,5 @@
 #	src/VBox/Additions/WINNT/Installer/ISO/ReadmeDrivers.txt
 #	src/VBox/Main/nls/*.ts
+#	src/VBox/ExtPacks/Puel/nls/*.ts
 #	*/*.inf, */*.rc
 
@@ -670,4 +671,6 @@
 # Whether to enable error message translation in Main.
 #VBOX_WITH_MAIN_NLS = 1
+# Whether to enable error message translation in Extension VM Pack.
+#VBOX_WITH_PUEL_NLS = 1
 # Set this to prefix all C symbols in XPCOM, to avoid dynamic linking problems
 # caused by our XPCOM library polluting the symbol namespace for system libs.
@@ -1244,10 +1247,17 @@
 
 #
-# Disable NLS support for only SDK builds
-#
+# VBOX_WITH_NLS controls all NLS (except the GUI at the moment).
+# We disable NLS for SDK-only builds.
+#
+if defined(VBOX_WITH_MAIN_NLS) || defined(VBOX_WITH_PUEL_NLS)
+ VBOX_WITH_NLS := 1
+endif
 ifdef VBOX_ONLY_SDK
- VBOX_WITH_MAIN_NLS =
-endif
-
+ override VBOX_WITH_NLS :=
+endif
+ifndef VBOX_WITH_NLS # (We test again to account for 'override VBOX_WITH_NLS :=')
+ VBOX_WITH_MAIN_NLS :=
+ VBOX_WITH_PUEL_NLS :=
+endif
 
 #
@@ -6985,5 +6995,6 @@
 # Qt
 #
-ifdef VBOX_WITH_QTGUI
+
+if defined(VBOX_WITH_QTGUI) || defined(VBOX_WITH_NLS)
 
  # Guess VBOX_WITH_ORACLE_QT
@@ -7083,136 +7094,137 @@
  TOOL_QT5_MOCFLAGS.darwin    += --include qconfig.h --include qglobal.h
 
- #
- # Template for building Qt GUI executables.
- #
- TEMPLATE_VBOXQTGUIEXE = VBox Qt GUI Executable
- TEMPLATE_VBOXQTGUIEXE_USES = qt5
- TEMPLATE_VBOXQTGUIEXE_QTTOOL = QT5
- TEMPLATE_VBOXQTGUIEXE_MOCTOOL = QT5
- TEMPLATE_VBOXQTGUIEXE_UICTOOL = QT5
- TEMPLATE_VBOXQTGUIEXE_RCCTOOL = QT5
- TEMPLATE_VBOXQTGUIEXE_LRCTOOL = QT5
- TEMPLATE_VBOXQTGUIEXE_SDKS = QT5
- TEMPLATE_VBOXQTGUIEXE_QT_INFIX = $(VBOX_QT_INFIX)
- TEMPLATE_VBOXQTGUIEXE_DEFS = IN_RING3 QT_NO_DEBUG QT_THREAD_SUPPORT QT_SHARED HAVE_CONFIG_H $(ARCH_BITS_DEFS)
- TEMPLATE_VBOXQTGUIEXE_RCDEFS = $(TEMPLATE_VBOXR3EXE_RCDEFS)
-
- ifeq ($(KBUILD_TARGET),win)
-  # Note! No use of VBOX_VCC_CRT_TYPE here yet as it requires a /MDd build of Qt as well.
-  TEMPLATE_VBOXQTGUIEXE_TOOL = $(VBOX_VCC_TOOL)
-  if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
-   TEMPLATE_VBOXQTGUIEXE_SDKS = WINSDK10-UCRT
-  endif
-  TEMPLATE_VBOXQTGUIEXE_DEFS += \
-     _WIN32_WINNT=0x0500 UNICODE _UNICODE \
-     QT_DLL _CRT_SECURE_NO_DEPRECATE \
-     $(QMAKE_PRL_DEFINES)
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS = -nologo -Zm200 -MD -Zi -EHsc -Zc:wchar_t-
-  #    -wd4481: nonstandard extension used: override specifier 'override'
-  #    -wd4625: 'QRubberBand' : copy constructor could not be generated because a base class copy constructor is inaccessible
-  #    -wd4626: 'QRubberBand' : assignment operator could not be generated because a base class assignment operator is inaccessible
-  #    -wd4640: qmetatype.h(2210): warning C4640: 'f' : construction of local static object is not thread-safe [too bad]
-  #    -wd4350: behavior change: 'int QStringList::indexOf(const QRegExp &,int) const' called instead of 'int QStringList::indexOf(QRegExp &,int) const'
-  #    -wd4121: UIActionPool.h(393) : warning C4121: 'UIActionPool::PointerToFunction' : alignment of a member was sensitive to packing
-  #    -wd4718: qmap.h(222) : warning C4718: 'QMapNode<enum DetailsElementType,bool>::destroySubTree' : recursive call has no side effects, deleting
-  #    -wd5204: pplwin.h(78): warning C5204: 'Concurrency::details::_DefaultPPLTaskScheduler': class has virtual functions
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_VCC_WARN_ALL) -wd4481 -wd4625 -wd4626 -wd4640 -wd4350 -wd4371 -wd4121 -wd4718 -wd5204 $(VBOX_VCC_WERR)
-  if "$(VBOX_VCC_TOOL_STEM)" >= "VCC120"
-   #   -wd4619: qvectro.h(305 : warning C4619: #pragma warning : there is no warning number '4345'
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -wd4619
-  endif
-  if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
-   #   -wd4774: string(530): warning C4774: '_scprintf' : format string expected in argument 1 is not a string literal
-   #   -wd4456: UICommon.cpp(1471): warning C4456: declaration of '_container_' hides previous local declaration  [nested foreach]
-   #   -wd4458: UISettingsDialogSpecific.cpp(416): warning C4458: declaration of 'data' hides class member
-   #            qwidget.h(730): note: see declaration of 'QWidget::data'
-   #   -wd4946: qmap.h(213): warning C4946: reinterpret_cast used between related classes: 'QMapNodeBase' and 'QMapNode<Key,T>'
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -wd4774 -wd4456 -wd4458 -wd4946
-  endif
-  ifdef VBOX_WITH_MSC_ANALYZE_THIS
-   TEMPLATE_VBOXR0DRV_CXXFLAGS += /analyze
-  endif
-
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug = -RTCsu
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug = -RTCsu
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt = $(NO_SUCH_VARIABLE)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS        = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.debug  = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.dbgopt = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt)
-  TEMPLATE_VBOXQTGUIEXE_LDFLAGS = -Ignore:4197 \
-	/NOD /INCREMENTAL:NO /MAPINFO:EXPORTS /LargeAddressAware /DynamicBase /NxCompat /Release /Debug /Opt:Ref /Opt:Icf \
-	/Version:$(VBOX_VERSION_MAJOR)0$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \
-	/STUB:$(PATH_ROOT)/src/VBox/HostDrivers/Support/win/winstub.com
-  if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_HARDENING)
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS += -IntegrityCheck
-  endif
-
-  TEMPLATE_VBOXQTGUIEXE_SDKS += $(VBOX_WINPSDK)
-  if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
-   TEMPLATE_VBOXQTGUIEXE_LIBS = \
-   	$(VBOX_LIBS_QT) \
-   	$(LIB_RUNTIME) \
-   	$(VBOX_LIB_VMM_LAZY) \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/vcruntime.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcrt.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcprt.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/oldnames.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
-  else
-   TEMPLATE_VBOXQTGUIEXE_LIBS = \
-   	$(VBOX_LIBS_QT) \
-   	$(LIB_RUNTIME) \
-   	$(VBOX_LIB_VMM_LAZY) \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcprt.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcrt.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/oldnames.lib \
-   	$(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
-  endif
-  TEMPLATE_VBOXQTGUIEXE_POST_CMDS = $(VBOX_SIGN_IMAGE_CMDS)
-
- else # the gcc guys:
-  TEMPLATE_VBOXQTGUIEXE_TOOL = $(VBOX_GCC_TOOL)
-  if $(VBOX_GCC_VERSION_CC) < 30400
-   TEMPLATE_VBOXQTGUIEXE_DEFS += RT_WITHOUT_PRAGMA_ONCE
-  endif
-  TEMPLATE_VBOXQTGUIEXE_DEFS.linux = _REENTRANT
-  TEMPLATE_VBOXQTGUIEXE_DEFS.solaris = _REENTRANT
-
-  ## @todo Use VBOX_GCC_PEDANTIC_CXX?
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS = \
+ ifdef VBOX_WITH_QTGUI
+  #
+  # Template for building Qt GUI executables.
+  #
+  TEMPLATE_VBOXQTGUIEXE = VBox Qt GUI Executable
+  TEMPLATE_VBOXQTGUIEXE_USES = qt5
+  TEMPLATE_VBOXQTGUIEXE_QTTOOL = QT5
+  TEMPLATE_VBOXQTGUIEXE_MOCTOOL = QT5
+  TEMPLATE_VBOXQTGUIEXE_UICTOOL = QT5
+  TEMPLATE_VBOXQTGUIEXE_RCCTOOL = QT5
+  TEMPLATE_VBOXQTGUIEXE_LRCTOOL = QT5
+  TEMPLATE_VBOXQTGUIEXE_SDKS = QT5
+  TEMPLATE_VBOXQTGUIEXE_QT_INFIX = $(VBOX_QT_INFIX)
+  TEMPLATE_VBOXQTGUIEXE_DEFS = IN_RING3 QT_NO_DEBUG QT_THREAD_SUPPORT QT_SHARED HAVE_CONFIG_H $(ARCH_BITS_DEFS)
+  TEMPLATE_VBOXQTGUIEXE_RCDEFS = $(TEMPLATE_VBOXR3EXE_RCDEFS)
+
+  ifeq ($(KBUILD_TARGET),win)
+   # Note! No use of VBOX_VCC_CRT_TYPE here yet as it requires a /MDd build of Qt as well.
+   TEMPLATE_VBOXQTGUIEXE_TOOL = $(VBOX_VCC_TOOL)
+   if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
+    TEMPLATE_VBOXQTGUIEXE_SDKS = WINSDK10-UCRT
+   endif
+   TEMPLATE_VBOXQTGUIEXE_DEFS += \
+      _WIN32_WINNT=0x0500 UNICODE _UNICODE \
+      QT_DLL _CRT_SECURE_NO_DEPRECATE \
+      $(QMAKE_PRL_DEFINES)
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS = -nologo -Zm200 -MD -Zi -EHsc -Zc:wchar_t-
+   #    -wd4481: nonstandard extension used: override specifier 'override'
+   #    -wd4625: 'QRubberBand' : copy constructor could not be generated because a base class copy constructor is inaccessible
+   #    -wd4626: 'QRubberBand' : assignment operator could not be generated because a base class assignment operator is inaccessible
+   #    -wd4640: qmetatype.h(2210): warning C4640: 'f' : construction of local static object is not thread-safe [too bad]
+   #    -wd4350: behavior change: 'int QStringList::indexOf(const QRegExp &,int) const' called instead of 'int QStringList::indexOf(QRegExp &,int) const'
+   #    -wd4121: UIActionPool.h(393) : warning C4121: 'UIActionPool::PointerToFunction' : alignment of a member was sensitive to packing
+   #    -wd4718: qmap.h(222) : warning C4718: 'QMapNode<enum DetailsElementType,bool>::destroySubTree' : recursive call has no side effects, deleting
+   #    -wd5204: pplwin.h(78): warning C5204: 'Concurrency::details::_DefaultPPLTaskScheduler': class has virtual functions
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_VCC_WARN_ALL) -wd4481 -wd4625 -wd4626 -wd4640 -wd4350 -wd4371 -wd4121 -wd4718 -wd5204 $(VBOX_VCC_WERR)
+   if "$(VBOX_VCC_TOOL_STEM)" >= "VCC120"
+    #   -wd4619: qvectro.h(305 : warning C4619: #pragma warning : there is no warning number '4345'
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -wd4619
+   endif
+   if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
+    #   -wd4774: string(530): warning C4774: '_scprintf' : format string expected in argument 1 is not a string literal
+    #   -wd4456: UICommon.cpp(1471): warning C4456: declaration of '_container_' hides previous local declaration  [nested foreach]
+    #   -wd4458: UISettingsDialogSpecific.cpp(416): warning C4458: declaration of 'data' hides class member
+    #            qwidget.h(730): note: see declaration of 'QWidget::data'
+    #   -wd4946: qmap.h(213): warning C4946: reinterpret_cast used between related classes: 'QMapNodeBase' and 'QMapNode<Key,T>'
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -wd4774 -wd4456 -wd4458 -wd4946
+   endif
+   ifdef VBOX_WITH_MSC_ANALYZE_THIS
+    TEMPLATE_VBOXR0DRV_CXXFLAGS += /analyze
+   endif
+
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug = -RTCsu
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug = -RTCsu
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt = $(NO_SUCH_VARIABLE)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS        = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.debug  = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.dbgopt = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt)
+   TEMPLATE_VBOXQTGUIEXE_LDFLAGS = -Ignore:4197 \
+		/NOD /INCREMENTAL:NO /MAPINFO:EXPORTS /LargeAddressAware /DynamicBase /NxCompat /Release /Debug /Opt:Ref /Opt:Icf \
+		/Version:$(VBOX_VERSION_MAJOR)0$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \
+		/STUB:$(PATH_ROOT)/src/VBox/HostDrivers/Support/win/winstub.com
+   if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_HARDENING)
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS += -IntegrityCheck
+   endif
+
+   TEMPLATE_VBOXQTGUIEXE_SDKS += $(VBOX_WINPSDK)
+   if "$(VBOX_VCC_TOOL_STEM)" >= "VCC140"
+    TEMPLATE_VBOXQTGUIEXE_LIBS = \
+   	 $(VBOX_LIBS_QT) \
+   	 $(LIB_RUNTIME) \
+   	 $(VBOX_LIB_VMM_LAZY) \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/vcruntime.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcrt.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcprt.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/oldnames.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
+   else
+    TEMPLATE_VBOXQTGUIEXE_LIBS = \
+   	 $(VBOX_LIBS_QT) \
+   	 $(LIB_RUNTIME) \
+   	 $(VBOX_LIB_VMM_LAZY) \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcprt.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/msvcrt.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/oldnames.lib \
+   	 $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
+   endif
+   TEMPLATE_VBOXQTGUIEXE_POST_CMDS = $(VBOX_SIGN_IMAGE_CMDS)
+
+  else # the gcc guys:
+   TEMPLATE_VBOXQTGUIEXE_TOOL = $(VBOX_GCC_TOOL)
+   if $(VBOX_GCC_VERSION_CC) < 30400
+    TEMPLATE_VBOXQTGUIEXE_DEFS += RT_WITHOUT_PRAGMA_ONCE
+   endif
+   TEMPLATE_VBOXQTGUIEXE_DEFS.linux = _REENTRANT
+   TEMPLATE_VBOXQTGUIEXE_DEFS.solaris = _REENTRANT
+
+   ## @todo Use VBOX_GCC_PEDANTIC_CXX?
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS = \
 	-g $(VBOX_GCC_pipe) $(filter-out -Wno-unused $(VBOX_GCC_Wno-unused-parameter),$(VBOX_GCC_WARN)) -frtti -fno-exceptions \
 	-Wno-long-long -fshort-wchar -fno-strict-aliasing \
 	$(VBOX_GCC_fvisibility-hidden) $(VBOX_GCC_fvisibility-inlines-hidden) $(VBOX_GCC_Wno-multistatement-macros) $(VBOX_GCC_Wno-ignored-qualifiers) \
 	$(VBOX_GCC_Wno-return-type-c-linkage) $(VBOX_GCC_std) $(VBOX_GCC_IPRT_FMT_CHECK) $(VBOX_GCC_SANITIZER_FLAGS)
-  ifdef VBOX_WITH_NO_GCC_WARNING_POLICY
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_GCC_WERR)
-  endif
-  ifn1of ($(USERNAME),dsen serkan) # Bunch of stuff deprecated after 5.6.*. These guys knows how to deal with it. :)
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_GCC_Wno-deprecated-declarations)
-  endif
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86 = -m32
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64 = -m64
-  TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux = -pthread
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS       = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.x86   = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.linux = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.debug = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug)
-  TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.dbgopt = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt)
-  TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS = -g $(VBOX_GCC_pipe) $(VBOX_GCC_PEDANTIC_C) -fno-exceptions $(VBOX_GCC_IPRT_FMT_CHECK)
-  TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.x86 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
-  TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
-  TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS = \
+   ifdef VBOX_WITH_NO_GCC_WARNING_POLICY
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_GCC_WERR)
+   endif
+   ifn1of ($(USERNAME),dsen serkan) # Bunch of stuff deprecated after 5.6.*. These guys knows how to deal with it. :)
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += $(VBOX_GCC_Wno-deprecated-declarations)
+   endif
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86 = -m32
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64 = -m64
+   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux = -pthread
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS       = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.x86   = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.linux = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.debug = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.debug)
+   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.dbgopt = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.dbgopt)
+   TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS = -g $(VBOX_GCC_pipe) $(VBOX_GCC_PEDANTIC_C) -fno-exceptions $(VBOX_GCC_IPRT_FMT_CHECK)
+   TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.x86 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
+   TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
+   TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS = \
 	-g $(VBOX_GCC_pipe) $(VBOX_GCC_PEDANTIC_CXX) \
 	-frtti -fno-exceptions $(VBOX_GCC_fvisibility-hidden) $(VBOX_GCC_fvisibility-inlines-hidden) $(VBOX_GCC_IPRT_FMT_CHECK)
-  ifdef VBOX_WITH_NO_GCC_WARNING_POLICY
-   TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS += $(VBOX_GCC_WERR)
-  endif
-  TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.x86 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
-  TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
-  TEMPLATE_VBOXQTGUIEXE_LDFLAGS = $(VBOX_GCC_SANITIZER_FLAGS) $(VBOX_GCC_SANITIZER_LDFLAGS)
-  TEMPLATE_VBOXQTGUIEXE_LDFLAGS.x86 = -m32
-  TEMPLATE_VBOXQTGUIEXE_LDFLAGS.amd64 = -m64
-  TEMPLATE_VBOXQTGUIEXE_LIBS = \
+   ifdef VBOX_WITH_NO_GCC_WARNING_POLICY
+    TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS += $(VBOX_GCC_WERR)
+   endif
+   TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.x86 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.x86)
+   TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.amd64 = $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.amd64)
+   TEMPLATE_VBOXQTGUIEXE_LDFLAGS = $(VBOX_GCC_SANITIZER_FLAGS) $(VBOX_GCC_SANITIZER_LDFLAGS)
+   TEMPLATE_VBOXQTGUIEXE_LDFLAGS.x86 = -m32
+   TEMPLATE_VBOXQTGUIEXE_LDFLAGS.amd64 = -m64
+   TEMPLATE_VBOXQTGUIEXE_LIBS = \
 	$(VBOX_LIBS_QT) \
 	$(LIB_RUNTIME) \
@@ -7220,118 +7232,143 @@
 	$(VBOX_LIB_VMM_LAZY)
 
-  ifeq ($(KBUILD_TARGET),linux)
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS += -Wl,-z,noexecstack,-z,relro $(VBOX_LD_as_needed)
+   ifeq ($(KBUILD_TARGET),linux)
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS += -Wl,-z,noexecstack,-z,relro $(VBOX_LD_as_needed)
+    TEMPLATE_VBOXQTGUIEXE_LIBS += \
+		$(VBOX_XCURSOR_LIBS) \
+		Xext \
+		X11
+    TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
+		$(VBOX_LIBPATH_X11)
+   else ifeq ($(KBUILD_TARGET),darwin)
+    TEMPLATE_VBOXQTGUIEXE_SDKS.darwin        += $(VBOX_DARWIN_DEF_SDK_SDKS)
+    TEMPLATE_VBOXQTGUIEXE_DEFS.darwin        += $(VBOX_DARWIN_DEF_SDK_DEFS)
+    TEMPLATE_VBOXQTGUIEXE_CFLAGS.darwin      += $(VBOX_DARWIN_DEF_SDK_CFLAGS)
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.darwin    += $(VBOX_DARWIN_DEF_SDK_CXXFLAGS)
+    TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.darwin    += $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.darwin)
+    TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.darwin   += $(VBOX_DARWIN_DEF_SDK_OBJCFLAGS)
+    TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.darwin += $(VBOX_DARWIN_DEF_SDK_OBJCXXFLAGS) $(VBOX_GCC_std)
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS.darwin     += $(VBOX_DARWIN_DEF_SDK_LDFLAGS) -bind_at_load -Wl,-headerpad_max_install_names
+    TEMPLATE_VBOXQTGUIEXE_LIBS +=
+    TEMPLATE_VBOXQTGUIEXE_LIBPATH +=
+   else
+    TEMPLATE_VBOXQTGUIEXE_INCS += \
+		$(VBOX_XCURSOR_INCS)
+    TEMPLATE_VBOXQTGUIEXE_LIBS += \
+		$(VBOX_XCURSOR_LIBS) \
+		Xext \
+		X11 \
+		m \
+		$(LIB_PTHREAD)
+    TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
+		$(VBOX_LIBPATH_X11)
+    ifeq ($(KBUILD_TARGET),freebsd)
+     TEMPLATE_VBOXQTGUIEXE_INCS += \
+		/usr/include \
+		/usr/X11R6/include \
+		/usr/local/include
+     TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
+		/usr/lib \
+		/usr/X11R6/lib \
+		/usr/local/lib
+    endif
+    ifeq ($(KBUILD_TARGET),solaris)
+     TEMPLATE_VBOXQTGUIEXE_LDFLAGS.solaris = -Wl,-z,ignore # Same as VBOX_LD_as_needed.
+     TEMPLATE_VBOXQTGUIEXE_LIBS += \
+         rt socket nsl
+    endif
+   endif
+   # Assume the Qt shared objects are in the same directory as the executable, on Solaris too.
+   ifdef VBOX_WITH_RUNPATH
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS += '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RUNPATH)'
+   else ifdef VBOX_WITH_RELATIVE_RUNPATH
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS += '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RELATIVE_RUNPATH)'
+   endif
+
+  endif
+
+  # Add COM/XPCOM stuff
+  TEMPLATE_VBOXQTGUIEXE_LIBS += \
+	$(PATH_STAGE_LIB)/VBoxCOM$(if-expr defined(VBOX_WITH_DEBUG_VCC_CRT) && $(KBUILD_TARGET) == win,-GUI,)$(VBOX_SUFF_LIB)
+  ifdef VBOX_WITH_XPCOM
+   ## @todo may be worth creating the VBOX_XPCOM SDK def, or just a SDK_VBOXXPCOM.
+   TEMPLATE_VBOXQTGUIEXE_DEFS += VBOX_WITH_XPCOM
+   ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+    TEMPLATE_VBOXQTGUIEXE_DEFS += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+   endif
+   TEMPLATE_VBOXQTGUIEXE_INCS += \
+	$(VBOX_XPCOM_INCS)
    TEMPLATE_VBOXQTGUIEXE_LIBS += \
-     $(VBOX_XCURSOR_LIBS) \
-	Xext \
-	X11
-    TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
-	$(VBOX_LIBPATH_X11)
-  else ifeq ($(KBUILD_TARGET),darwin)
-   TEMPLATE_VBOXQTGUIEXE_SDKS.darwin        += $(VBOX_DARWIN_DEF_SDK_SDKS)
-   TEMPLATE_VBOXQTGUIEXE_DEFS.darwin        += $(VBOX_DARWIN_DEF_SDK_DEFS)
-   TEMPLATE_VBOXQTGUIEXE_CFLAGS.darwin      += $(VBOX_DARWIN_DEF_SDK_CFLAGS)
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.darwin    += $(VBOX_DARWIN_DEF_SDK_CXXFLAGS)
-   TEMPLATE_VBOXQTGUIEXE_PCHFLAGS.darwin    += $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.darwin)
-   TEMPLATE_VBOXQTGUIEXE_OBJCFLAGS.darwin   += $(VBOX_DARWIN_DEF_SDK_OBJCFLAGS)
-   TEMPLATE_VBOXQTGUIEXE_OBJCXXFLAGS.darwin += $(VBOX_DARWIN_DEF_SDK_OBJCXXFLAGS) $(VBOX_GCC_std)
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS.darwin     += $(VBOX_DARWIN_DEF_SDK_LDFLAGS) -bind_at_load -Wl,-headerpad_max_install_names
-   TEMPLATE_VBOXQTGUIEXE_LIBS +=
-   TEMPLATE_VBOXQTGUIEXE_LIBPATH +=
-  else
+	$(LIB_XPCOM)
+   TEMPLATE_VBOXQTGUIEXE_INTERMEDIATES += \
+	$(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
+  else  # COM
    TEMPLATE_VBOXQTGUIEXE_INCS += \
-	$(VBOX_XCURSOR_INCS)
-   TEMPLATE_VBOXQTGUIEXE_LIBS += \
-     $(VBOX_XCURSOR_LIBS) \
-	Xext \
-	X11 \
-	m \
-	$(LIB_PTHREAD)
-   TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
-	$(VBOX_LIBPATH_X11)
-   ifeq ($(KBUILD_TARGET),freebsd)
-    TEMPLATE_VBOXQTGUIEXE_INCS += \
-	/usr/include \
-	/usr/X11R6/include \
-	/usr/local/include
-    TEMPLATE_VBOXQTGUIEXE_LIBPATH += \
-	/usr/lib \
-	/usr/X11R6/lib \
-	/usr/local/lib
-   endif
-   ifeq ($(KBUILD_TARGET),solaris)
-    TEMPLATE_VBOXQTGUIEXE_LDFLAGS.solaris = -Wl,-z,ignore # Same as VBOX_LD_as_needed.
-    TEMPLATE_VBOXQTGUIEXE_LIBS += \
-         rt socket nsl
-   endif
-  endif
-  # Assume the Qt shared objects are in the same directory as the executable, on Solaris too.
-  ifdef VBOX_WITH_RUNPATH
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS += '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RUNPATH)'
-  else ifdef VBOX_WITH_RELATIVE_RUNPATH
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS += '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RELATIVE_RUNPATH)'
-  endif
-
- endif
-
- # Add COM/XPCOM stuff
- TEMPLATE_VBOXQTGUIEXE_LIBS += \
-	$(PATH_STAGE_LIB)/VBoxCOM$(if-expr defined(VBOX_WITH_DEBUG_VCC_CRT) && $(KBUILD_TARGET) == win,-GUI,)$(VBOX_SUFF_LIB)
- ifdef VBOX_WITH_XPCOM
-  ## @todo may be worth creating the VBOX_XPCOM SDK def, or just a SDK_VBOXXPCOM.
-  TEMPLATE_VBOXQTGUIEXE_DEFS += VBOX_WITH_XPCOM
-  ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
-   TEMPLATE_VBOXQTGUIEXE_DEFS += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
-  endif
-  TEMPLATE_VBOXQTGUIEXE_INCS += \
-	$(VBOX_XPCOM_INCS)
-  TEMPLATE_VBOXQTGUIEXE_LIBS += \
-	$(LIB_XPCOM)
-  TEMPLATE_VBOXQTGUIEXE_INTERMEDIATES += \
-	$(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
- else  # COM
-  TEMPLATE_VBOXQTGUIEXE_INCS += \
 	$(VBOX_PATH_SDK)/bindings/mscom/include
-  TEMPLATE_VBOXQTGUIEXE_INTERMEDIATES += \
+   TEMPLATE_VBOXQTGUIEXE_INTERMEDIATES += \
 	$(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h
- endif # COM
-
- ifn1of ($(KBUILD_TARGET), darwin os2 win)
-   TEMPLATE_VBOXQTGUIEXE_DEFS     += PIC
-   TEMPLATE_VBOXQTGUIEXE_CFLAGS   += -fPIC
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -fPIC
-   # Needed for GCC 9. Even system's Qt 5.12.4 (on Ubuntu 19.10) did not have this fixed yet.
-   TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux = -Wno-deprecated-copy $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
-   TEMPLATE_VBOXQTGUIEXE_LDFLAGS  += -fPIC
- endif # not darwin, os2 or win
-
- ifeq ($(KBUILD_TARGET),darwin)
-  TEMPLATE_VBOXQTGUIEXE_POST_CMDS = $(QUIET)install_name_tool $(foreach qtmod, $(VBOX_QT_MOD_NAMES), \
+  endif # COM
+
+  ifn1of ($(KBUILD_TARGET), darwin os2 win)
+    TEMPLATE_VBOXQTGUIEXE_DEFS     += PIC
+    TEMPLATE_VBOXQTGUIEXE_CFLAGS   += -fPIC
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS += -fPIC
+    # Needed for GCC 9. Even system's Qt 5.12.4 (on Ubuntu 19.10) did not have this fixed yet.
+    TEMPLATE_VBOXQTGUIEXE_CXXFLAGS.linux = -Wno-deprecated-copy $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
+    TEMPLATE_VBOXQTGUIEXE_LDFLAGS  += -fPIC
+  endif # not darwin, os2 or win
+
+  ifeq ($(KBUILD_TARGET),darwin)
+   TEMPLATE_VBOXQTGUIEXE_POST_CMDS = $(QUIET)install_name_tool $(foreach qtmod, $(VBOX_QT_MOD_NAMES), \
 	$(foreach prefix, @executable_path/../Frameworks/ $(VBOX_PATH_QT)/Frameworks/ $(PATH_SDK_QT5)/, \
 		-change "$(prefix)$(qtmod).framework/Versions/5/$(qtmod)" \
 			"$(if $(VBOX_WITH_HARDENING),/Applications/VirtualBox.app/Contents/Frameworks,@rpath)/$(qtmod).framework/Versions/5/$(qtmod)" ) ) "$(out)"
- endif
-
- #
- # Template for building Qt GUI components.
- #
- TEMPLATE_VBOXQTGUI = VBox Qt GUI Components
- TEMPLATE_VBOXQTGUI_EXTENDS = VBOXQTGUIEXE
- TEMPLATE_VBOXQTGUI_LIBS = $(filter-out $(QTMAIN),$(TEMPLATE_VBOXQTGUIEXE_LIBS))
- ifeq ($(KBUILD_TARGET),darwin)
-  TEMPLATE_VBOXQTGUI_LDFLAGS.darwin += $(filter-out -bind_at_load,$(TEMPLATE_VBOXQTGUIEXE_LDFLAGS.darwin)) \
+  endif
+
+  #
+  # Template for building Qt GUI components.
+  #
+  TEMPLATE_VBOXQTGUI = VBox Qt GUI Components
+  TEMPLATE_VBOXQTGUI_EXTENDS = VBOXQTGUIEXE
+  TEMPLATE_VBOXQTGUI_LIBS = $(filter-out $(QTMAIN),$(TEMPLATE_VBOXQTGUIEXE_LIBS))
+  ifeq ($(KBUILD_TARGET),darwin)
+   TEMPLATE_VBOXQTGUI_LDFLAGS.darwin += $(filter-out -bind_at_load,$(TEMPLATE_VBOXQTGUIEXE_LDFLAGS.darwin)) \
 	-current_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \
 	-compatibility_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD)
- endif
- ifn1of ($(KBUILD_TARGET), darwin os2 win)
-   TEMPLATE_VBOXQTGUI_DEFS     = PIC $(TEMPLATE_VBOXQTGUIEXE_DEFS)
-   TEMPLATE_VBOXQTGUI_CFLAGS   = -fPIC $(TEMPLATE_VBOXQTGUIEXE_CFLAGS)
-   TEMPLATE_VBOXQTGUI_CXXFLAGS = -fPIC $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
-   TEMPLATE_VBOXQTGUI_PCHFLAGS = $(TEMPLATE_VBOXQTGUI_CXXFLAGS)
-   TEMPLATE_VBOXQTGUI_LDFLAGS  = -fPIC $(TEMPLATE_VBOXQTGUIEXE_LDFLAGS)
- endif
-
-endif # VBOX_WITH_QTGUI
-
+  endif
+  ifn1of ($(KBUILD_TARGET), darwin os2 win)
+    TEMPLATE_VBOXQTGUI_DEFS     = PIC $(TEMPLATE_VBOXQTGUIEXE_DEFS)
+    TEMPLATE_VBOXQTGUI_CFLAGS   = -fPIC $(TEMPLATE_VBOXQTGUIEXE_CFLAGS)
+    TEMPLATE_VBOXQTGUI_CXXFLAGS = -fPIC $(TEMPLATE_VBOXQTGUIEXE_CXXFLAGS)
+    TEMPLATE_VBOXQTGUI_PCHFLAGS = $(TEMPLATE_VBOXQTGUI_CXXFLAGS)
+    TEMPLATE_VBOXQTGUI_LDFLAGS  = -fPIC $(TEMPLATE_VBOXQTGUIEXE_LDFLAGS)
+  endif
+ endif # VBOX_WITH_QTGUI
+
+ ifdef VBOX_WITH_NLS
+  #
+  # Template for translation compilation.
+  # Made as simple program without installing itself.
+  # To archive it, the dummy code without runtime is used,
+  # i.e. only compiler and system standard libs are linked.
+  #
+  TEMPLATE_VBoxNLS = VBox NLS template for installing translation files
+  TEMPLATE_VBoxNLS_EXTENDS = VBoxR3Static
+  TEMPLATE_VBoxNLS_USES = qt5
+  TEMPLATE_VBoxNLS_QTTOOL = QT5
+  TEMPLATE_VBoxNLS_QT_INFIX = $(VBOX_QT_INFIX)
+  TEMPLATE_VBoxNLS_INSTTYPE = none
+  TEMPLATE_VBoxNLS_LRCFLAGS += -silent
+  TEMPLATE_VBoxNLS_QT_TRANSLATIONS_INST = $(INST_BIN)nls/
+  TEMPLATE_VBoxNLS_SOURCES = \
+	$(PATH_ROOT)/src/VBox/Main/nls/dummy.c
+  TEMPLATE_VBoxNLS_LIBS =\
+	$(filter-out \
+		$(VBOX_LIB_RUNTIME_STATIC) \
+		$(PATH_STAGE_LIB)/VBox-libxml2-static$(VBOX_SUFF_LIB), \
+		$(TEMPLATE_VBoxR3Static_LIBS))
+
+ endif # !VBOX_WITH_NLS
+
+endif # VBOX_WITH_QTGUI || VBOX_WITH_NLS
 
 #
Index: /trunk/include/VBox/ExtPack/ExtPack.h
===================================================================
--- /trunk/include/VBox/ExtPack/ExtPack.h	(revision 91311)
+++ /trunk/include/VBox/ExtPack/ExtPack.h	(revision 91312)
@@ -327,4 +327,26 @@
                                                        VBOXEXTPACK_IF_CS(IVetoEvent) **ppEventOut));
 
+    /**
+     * Translate the string using registered translation files.
+     *
+     * Translation files are excluded from translation engine. Although
+     * the already loaded translation remains in the translation cache the new
+     * translation will not be loaded after returning from the function if the
+     * user changes the language.
+     *
+     * @returns Translated string on success the pszSourceText otherwise.
+     * @param   pHlp                      Pointer to this helper structure.
+     * @param   aComponent                Translation context e.g. class name
+     * @param   pszSourceText             String to translate
+     * @param   pszComment                Comment to the string to resolve possible ambiguities
+     *                                    (NULL means no comment).
+     * @param   iNum                      Number used to define plural form of the translation
+     */
+    DECLR3CALLBACKMEMBER(const char *, pfnTranslate,(PCVBOXEXTPACKHLP pHlp,
+                                                     const char *pszComponent,
+                                                     const char *pszSourceText,
+                                                     const char *pszComment,
+                                                     const int   iNum));
+
     DECLR3CALLBACKMEMBER(int, pfnReserved1,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
     DECLR3CALLBACKMEMBER(int, pfnReserved2,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
@@ -338,5 +360,5 @@
 } VBOXEXTPACKHLP;
 /** Current version of the VBOXEXTPACKHLP structure.  */
-#define VBOXEXTPACKHLP_VERSION          RT_MAKE_U32(4, 0)
+#define VBOXEXTPACKHLP_VERSION          RT_MAKE_U32(5, 0)
 
 
@@ -357,4 +379,6 @@
     /** The VirtualBox version this extension pack was built against.  */
     uint32_t                    uVBoxVersion;
+    /** Translation files base name. */
+    const char                 *pszNlsBaseName;
 
     /**
@@ -439,5 +463,5 @@
 } VBOXEXTPACKREG;
 /** Current version of the VBOXEXTPACKREG structure.  */
-#define VBOXEXTPACKREG_VERSION        RT_MAKE_U32(2, 0)
+#define VBOXEXTPACKREG_VERSION        RT_MAKE_U32(3, 0)
 
 
@@ -482,4 +506,6 @@
     /** The VirtualBox version this extension pack was built against.  */
     uint32_t                    uVBoxVersion;
+    /** Translation files base name. */
+    const char                 *pszNlsBaseName;
 
     /**
@@ -552,5 +578,5 @@
 } VBOXEXTPACKVMREG;
 /** Current version of the VBOXEXTPACKVMREG structure.  */
-#define VBOXEXTPACKVMREG_VERSION      RT_MAKE_U32(2, 0)
+#define VBOXEXTPACKVMREG_VERSION      RT_MAKE_U32(3, 0)
 
 
Index: /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMain.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMain.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMain.cpp	(revision 91312)
@@ -84,4 +84,5 @@
     VBOXEXTPACKREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnInstalled =      */  NULL,
     /* .pfnUninstall =      */  NULL,
Index: /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMainVM.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMainVM.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/BusMouseSample/VBoxBusMouseMainVM.cpp	(revision 91312)
@@ -128,4 +128,5 @@
     VBOXEXTPACKVMREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnConsoleReady =   */  NULL,
     /* .pfnUnload =         */  NULL,
Index: /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMain.cpp	(revision 91312)
@@ -84,4 +84,5 @@
     VBOXEXTPACKREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnInstalled =      */  NULL,
     /* .pfnUninstall =      */  NULL,
Index: /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMainVM.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMainVM.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/Skeleton/VBoxSkeletonMainVM.cpp	(revision 91312)
@@ -84,4 +84,5 @@
     VBOXEXTPACKVMREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnConsoleReady =   */  NULL,
     /* .pfnUnload =         */  NULL,
Index: /trunk/src/VBox/ExtPacks/VBoxDTrace/VBoxDTraceMain.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/VBoxDTrace/VBoxDTraceMain.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/VBoxDTrace/VBoxDTraceMain.cpp	(revision 91312)
@@ -84,4 +84,5 @@
     VBOXEXTPACKREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnInstalled =      */  NULL,
     /* .pfnUninstall =      */  NULL,
Index: /trunk/src/VBox/ExtPacks/VNC/VBoxVNCMain.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/VNC/VBoxVNCMain.cpp	(revision 91311)
+++ /trunk/src/VBox/ExtPacks/VNC/VBoxVNCMain.cpp	(revision 91312)
@@ -71,4 +71,5 @@
     VBOXEXTPACKREG_VERSION,
     /* .uVBoxFullVersion =  */  VBOX_FULL_VERSION,
+    /* .pszNlsBaseName =    */  NULL,
     /* .pfnInstalled =      */  NULL,
     /* .pfnUninstall =      */  NULL,
Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 91311)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 91312)
@@ -1321,4 +1321,10 @@
 endif
 
+# define qt5 tools for translation even if VBOX_ONLY_EXTPACKS is enabled
+ifdef VBOX_WITH_NLS
+ USES += qt5
+endif
+
+
 endif # !VBOX_ONLY_SDK
 
@@ -1416,57 +1422,19 @@
 # NLS stuff.
 #
+
+#
+# Include the language lists.
+#
+include $(PATH_SUB_CURRENT)/nls/ApprovedLanguages.kmk
+
 PROGRAMS += VirtualBoxAPI
-VirtualBoxAPI_TEMPLATE = VBOXQTGUIEXE
-VirtualBoxAPI_INSTTYPE = none
-VirtualBoxAPI_LRCFLAGS = -silent
+VirtualBoxAPI_TEMPLATE = VBoxNLS
 VirtualBoxAPI_QT_TRANSLATIONS_INST = $(INST_BIN)nls/
-VirtualBoxAPI_APPROVED_LANGUAGES = \
-	bg \
-	ca \
-	ca_VA \
-	cs \
-	da \
-	de \
-	el \
-	en \
-	es \
-	eu \
-	fa \
-	fi \
-	fr \
-	gl \
-	he \
-	hr_HR \
-	hu \
-	id \
-	it \
-	ja \
-	km_KH \
-	ko \
-	lt \
-	nl \
-	pl \
-	pt \
-	pt_BR \
-	ro \
-	ru \
-	sk \
-	sl \
-	sr \
-	sv \
-	th \
-	tr \
-	uk \
-	zh_CN \
-	zh_TW
-
 VirtualBoxAPI_QT_TRANSLATIONS = \
 	$(filter \
 		$(addsuffix .ts, $(addprefix $(VBOX_PATH_MAIN_SRC)/nls/VirtualBoxAPI_, \
-			$(VirtualBoxAPI_APPROVED_LANGUAGES))), \
+			$(VBOX_APPROVED_MAIN_LANGUAGES))), \
 		$(wildcard $(VBOX_PATH_MAIN_SRC)/nls/*.ts))
 
-VirtualBoxAPI_SOURCES = \
-	nls/dummy.c
 VirtualBoxAPI_VBOX_ALL_NLS_SOURCES = $(wildcard \
 	$(VBOX_PATH_MAIN_SRC)/include/*.h\
@@ -1488,14 +1456,14 @@
 		$(VBOX_PATH_MAIN_SRC)/nls/VirtualBoxAPI_xx_YY.ts
 
-fake-main-nls:
-	$(foreach file, $(VirtualBoxAPI_QT_TRANSLATIONS) \
-	,$(NLTAB)$(SED) -i \
-       	-e '/<source>.*<\/source>/h' \
-       	-e '/<source>.*<\/source>/p' \
-       	-e '/<translation type="unfinished"><\/translation>/{' \
-       		-e 'x' \
-       		-e 's/<source>\(.*\)<\/source>/<translation type="unfinished">$(notdir $(file)): \1<\/translation>/' \
-       	-e '}' \
-		$(file) )
+#fake-main-nls:
+#	$(foreach file, $(VirtualBoxAPI_QT_TRANSLATIONS) \
+#	,$(NLTAB)$(SED) -i \
+#       	-e '/<source>.*<\/source>/h' \
+#       	-e '/<source>.*<\/source>/p' \
+#       	-e '/<translation type="unfinished"><\/translation>/{' \
+#       		-e 'x' \
+#       		-e 's/<source>\(.*\)<\/source>/<translation type="unfinished">$(notdir $(file)): \1<\/translation>/' \
+#       	-e '}' \
+#		$(file) )
 
 
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 91312)
@@ -102,5 +102,5 @@
     do { \
         if (!!(drv)) {} \
-        else return setError(E_ACCESSDENIED, tr("The console is not powered up (%Rfn)"), __FUNCTION__); \
+        else return setError(E_ACCESSDENIED, Console::tr("The console is not powered up (%Rfn)"), __FUNCTION__); \
     } while (0)
 
Index: /trunk/src/VBox/Main/include/ConsoleVRDPServer.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 91312)
@@ -61,5 +61,5 @@
 
 /* Member of Console. Helper class for VRDP server management. Not a COM class. */
-class ConsoleVRDPServer : public VirtualBoxTranslatable
+class ConsoleVRDPServer
 {
 public:
Index: /trunk/src/VBox/Main/include/DHCPConfigImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/DHCPConfigImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/DHCPConfigImpl.h	(revision 91312)
@@ -41,5 +41,5 @@
  * can call setError and such on.
  */
-class DHCPConfig : public VirtualBoxTranslatable
+class DHCPConfig
 {
 protected:
Index: /trunk/src/VBox/Main/include/ExtPackManagerImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 91312)
@@ -182,5 +182,10 @@
                                                        /* VBoxEventType_T */ uint32_t aType,
                                                        VBOXEXTPACK_IF_CS(IVetoEvent) **ppEventOut);
-    static DECLCALLBACK(int)    i_hlpReservedN(PCVBOXEXTPACKHLP pHlp);
+    static DECLCALLBACK(const char *) i_hlpTranslate(PCVBOXEXTPACKHLP pHlp,
+                                                     const char *pszComponent,
+                                                     const char *pszSourceText,
+                                                     const char *pszComment = NULL,
+                                                     const int   iNum = -1);
+    static DECLCALLBACK(int)      i_hlpReservedN(PCVBOXEXTPACKHLP pHlp);
     /** @}  */
 
Index: /trunk/src/VBox/Main/include/GuestDnDPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestDnDPrivate.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/GuestDnDPrivate.h	(revision 91312)
@@ -800,5 +800,5 @@
  * Class for keeping a DnD guest state around.
  */
-class GuestDnDState : public VirtualBoxTranslatable
+class GuestDnDState
 {
 
Index: /trunk/src/VBox/Main/include/GuestProcessImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 91312)
@@ -214,5 +214,5 @@
  * information extraction and maintaining the overall status.
  */
-class GuestProcessTool : public VirtualBoxTranslatable
+class GuestProcessTool
 {
 public:
Index: /trunk/src/VBox/Main/include/GuestSessionImplTasks.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 91312)
@@ -156,5 +156,4 @@
 class GuestSessionTask
     : public ThreadTask
-    , public VirtualBoxTranslatable
 {
 public:
Index: /trunk/src/VBox/Main/include/MachineImplCloneVM.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImplCloneVM.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/MachineImplCloneVM.h	(revision 91312)
@@ -28,5 +28,5 @@
 struct MachineCloneVMPrivate;
 
-class MachineCloneVM : public VirtualBoxTranslatable
+class MachineCloneVM
 {
 public:
Index: /trunk/src/VBox/Main/include/MachineImplMoveVM.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImplMoveVM.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/MachineImplMoveVM.h	(revision 91312)
@@ -64,5 +64,5 @@
 struct fileList_t;
 
-class MachineMoveVM : public ThreadTask, public VirtualBoxTranslatable
+class MachineMoveVM : public ThreadTask
 {
     std::vector<ComObjPtr<Machine> >        machineList;
Index: /trunk/src/VBox/Main/include/TextScript.h
===================================================================
--- /trunk/src/VBox/Main/include/TextScript.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/TextScript.h	(revision 91312)
@@ -34,5 +34,4 @@
 class AbstractScript
     : public RTCNonCopyable
-    , public VirtualBoxTranslatable
 {
 protected:
Index: /trunk/src/VBox/Main/include/USBProxyService.h
===================================================================
--- /trunk/src/VBox/Main/include/USBProxyService.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/USBProxyService.h	(revision 91312)
@@ -43,6 +43,5 @@
  */
 class USBProxyService
-    : public VirtualBoxTranslatable
-    , public Lockable
+    : public Lockable
 {
 public:
Index: /trunk/src/VBox/Main/include/UnattendedInstaller.h
===================================================================
--- /trunk/src/VBox/Main/include/UnattendedInstaller.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/UnattendedInstaller.h	(revision 91312)
@@ -36,5 +36,5 @@
  * execute an unattended installation
  */
-class UnattendedInstaller : public RTCNonCopyable, public VirtualBoxTranslatable
+class UnattendedInstaller : public RTCNonCopyable
 {
 /*data*/
Index: /trunk/src/VBox/Main/include/VirtualBoxBase.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxBase.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/VirtualBoxBase.h	(revision 91312)
@@ -364,5 +364,5 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \
+            return setError(E_INVALIDARG, VirtualBoxBase::tr("Argument %s is NULL"), #arg); \
     } while (0)
 
@@ -377,5 +377,6 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #arg); \
+            return setError(E_INVALIDARG, \
+                            VirtualBoxBase::tr("Argument %s is an invalid pointer"), #arg); \
     } while (0)
 
@@ -391,5 +392,5 @@
         else \
             return setError(E_POINTER, \
-                tr("Argument %s points to invalid memory location (%p)"), \
+                VirtualBoxBase::tr("Argument %s points to invalid memory location (%p)"), \
                 #arg, (void *)(arg)); \
     } while (0)
@@ -405,5 +406,6 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \
+            return setError(E_INVALIDARG, \
+                            VirtualBoxBase::tr("Argument %s is NULL"), #arg); \
     } while (0)
 
@@ -419,5 +421,6 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #a_bstrIn); \
+            return setError(E_INVALIDARG, \
+                            VirtualBoxBase::tr("Argument %s is an invalid pointer"), #a_bstrIn); \
     } while (0)
 /**
@@ -432,5 +435,7 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s is empty or an invalid pointer"), #a_bstrIn); \
+            return setError(E_INVALIDARG, \
+                            VirtualBoxBase::tr("Argument %s is empty or an invalid pointer"), \
+                            #a_bstrIn); \
     } while (0)
 
@@ -450,5 +455,6 @@
         else \
             return setError(E_INVALIDARG, \
-                tr("GUID argument %s is not valid (\"%ls\")"), #a_Arg, Bstr(a_Arg).raw()); \
+                            VirtualBoxBase::tr("GUID argument %s is not valid (\"%ls\")"), \
+                            #a_Arg, Bstr(a_Arg).raw()); \
     } while (0)
 
@@ -465,5 +471,6 @@
         else \
             return setError(E_INVALIDARG, \
-                tr("Argument %s is invalid (must be %s)"), #arg, #expr); \
+                            VirtualBoxBase::tr("Argument %s is invalid (must be %s)"), \
+                            #arg, #expr); \
     } while (0)
 
@@ -482,5 +489,5 @@
         { /* likely */ }\
         else \
-            return setError(E_INVALIDARG, tr("Argument %s %s"), \
+            return setError(E_INVALIDARG, VirtualBoxBase::tr("Argument %s %s"), \
                             #arg, Utf8StrFmt msg .c_str()); \
     } while (0)
@@ -497,6 +504,6 @@
         else \
             return setError(E_POINTER, \
-                tr("Output argument %s points to invalid memory location (%p)"), \
-                #arg, (void *)(arg)); \
+                            VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
+                            #arg, (void *)(arg)); \
     } while (0)
 
@@ -512,5 +519,5 @@
         else \
             return setError(E_POINTER, \
-                            tr("Output argument %s points to invalid memory location (%p)"), \
+                            VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
                             #arg, (void*)(arg)); \
     } while (0)
@@ -521,5 +528,5 @@
 #define ReturnComNotImplemented() \
     do { \
-        return setError(E_NOTIMPL, tr("Method %s is not implemented"), __FUNCTION__); \
+        return setError(E_NOTIMPL, VirtualBoxBase::tr("Method %s is not implemented"), __FUNCTION__); \
     } while (0)
 
@@ -562,54 +569,4 @@
 #endif
 
-/**
- * Parent class of VirtualBoxBase which enables translation support (which
- * Main doesn't have yet, but this provides the tr() function which will one
- * day provide translations).
- *
- * This class sits in between Lockable and VirtualBoxBase only for the one
- * reason that the USBProxyService wants translation support but is not
- * implemented as a COM object, which VirtualBoxBase implies.
- */
-class ATL_NO_VTABLE VirtualBoxTranslatable
-{
-public:
-    /**
-     * Returns translated text.
-     *
-     * @param aComponent    Translation context e.g. class name
-     * @param aSourceText   String to translate.
-     * @param aComment      Comment to the string to resolve possible ambiguities
-     *                      (NULL means no comment). Used by translation tool only.
-     * @param aNum          Number used to define plural form of the translation.
-     *
-     * @return Translated text.
-     */
-    static const char *translate(const char *aComponent,
-                                 const char *aSourceText,
-                                 const char *aComment = NULL,
-                                 const int   aNum = -1)
-    {
-#ifdef VBOX_WITH_MAIN_NLS
-        return VirtualBoxTranslator::translate(aComponent, aSourceText, aComment, aNum);
-#else
-        RT_NOREF(aComponent, aComment, aNum);
-        return aSourceText;
-#endif
-    }
-
-    /**
-     * Returns source text stored in the cache if exists.
-     * Otherwise, the @a aTranslation itself returned.
-     */
-    static const char *trSource(const char *aTranslation)
-    {
-#ifdef VBOX_WITH_MAIN_NLS
-        return VirtualBoxTranslator::trSource(aTranslation);
-#else
-        return aTranslation;
-#endif
-    }
-};
-
 ////////////////////////////////////////////////////////////////////////////////
 //
@@ -624,5 +581,5 @@
                                  const int   aNum = -1) \
     { \
-        return VirtualBoxTranslatable::translate(#cls, aSourceText, aComment, aNum); \
+        return VirtualBoxTranslator::translate(NULL, #cls, aSourceText, aComment, aNum); \
     }
 #else
@@ -718,6 +675,5 @@
  */
 class ATL_NO_VTABLE VirtualBoxBase
-    : public VirtualBoxTranslatable
-    , public Lockable
+    : public Lockable
     , public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>
 #if !defined (VBOX_WITH_XPCOM)
@@ -873,6 +829,6 @@
  * Dummy macro that is used to shut down Qt's lupdate tool warnings in some
  * situations. This macro needs to be present inside (better at the very
- * beginning) of the declaration of the class that inherits from
- * VirtualBoxTranslatable, to make lupdate happy.
+ * beginning) of the declaration of the class that uses translation, to make
+ * lupdate happy.
  */
 #define Q_OBJECT
Index: /trunk/src/VBox/Main/include/VirtualBoxClientImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxClientImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/VirtualBoxClientImpl.h	(revision 91312)
@@ -106,4 +106,5 @@
 #ifdef VBOX_WITH_MAIN_NLS
         VirtualBoxTranslator *m_pVBoxTranslator;
+        TRCOMPONENT           m_pTrComponent;
 #endif
     };
Index: /trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h	(revision 91312)
@@ -31,5 +31,4 @@
 #ifndef VBOX_WITH_XPCOM /* IErrorInfo doesn't inherit from IDispatch, ugly 3am hack: */
     , public IDispatch
-    , public VirtualBoxTranslatable
 #endif
 {
Index: /trunk/src/VBox/Main/include/VirtualBoxTranslator.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxTranslator.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/VirtualBoxTranslator.h	(revision 91312)
@@ -27,4 +27,5 @@
 #include <VBox/com/AutoLock.h>
 
+typedef void *TRCOMPONENT;
 
 class QMTranslator;
@@ -46,10 +47,33 @@
 
     /**
+     * Adds path containing translation files into list of known paths.
+     * Path should include translation file prefix.
+     *
+     * @returns VBox status code
+     * @param aTranslationPath   Path to translation files including file prefix
+     * @param aDefault           Use as default translation component, i.e.
+     *                           Use this path for translation if component
+     *                           is NULL
+     * @param aComponent         Where is the pointer to component returned
+     */
+    static int registerTranslation(const char *aTranslationPath,
+                                   bool aDefault,
+                                   TRCOMPONENT *aComponent);
+
+    /**
+     * Removes the path from list of known paths.
+     * Does not remove already loaded translation from string cache.
+     */
+    static int unregisterTranslation(TRCOMPONENT aComponent);
+
+    /**
      * Translates @a aSourceText to user language.
+     * Uses component marked as default if @a aTranslationComponent is NULL
      *
-     * @returns Translated string or @a aSourceText.  The returned string is
-     *          valid only during lifetime of the this translator instance.
+     * @returns Translated string or @a aSourceText. The returned string is
+     *          valid only during lifetime of the translator instance.
      */
-    static const char *translate(const char *aContext,
+    static const char *translate(TRCOMPONENT aComponent,
+                                 const char *aContext,
                                  const char *aSourceText,
                                  const char *aComment = NULL,
@@ -64,7 +88,4 @@
     /* Convenience function used by VirtualBox::init */
     int i_loadLanguage(const char *pszLang);
-    int i_setLanguageFile(const char *aFileName);
-    com::Utf8Str i_languageFile();
-
 
     static int32_t initCritSect();
@@ -76,6 +97,20 @@
     uint32_t m_cInstanceRefs;
 
-    com::Utf8Str  m_strLangFileName;
-    QMTranslator *m_pTranslator;
+    struct TranslatorComponent
+    {
+        QMTranslator *pTranslator;
+        /* Path to translation files. It includes file prefix, i.e
+         * /path/to/folder/file_prefix */
+        com::Utf8Str  strPath;
+
+        TranslatorComponent() : pTranslator(NULL) {}
+    };
+    typedef std::list<TranslatorComponent> TranslatorList;
+    TranslatorList  m_lTranslators;
+    TranslatorComponent *m_pDefaultComponent;
+
+    /* keep the language code for registration */
+    com::Utf8Str m_strLanguage;
+
     /** String cache that all translation strings are stored in.
      * This is a add-only cache, which allows translate() to return C-strings w/o
@@ -87,9 +122,19 @@
     VirtualBoxTranslator();
 
-    const char *i_translate(const char *aContext,
+    int i_loadLanguageForComponent(TranslatorComponent *aComponent, const char *aLang);
+
+    int i_setLanguageFile(TranslatorComponent *aComponent, const char *aFileName);
+
+    int i_registerTranslation(const char *aTranslationPath,
+                              bool aDefault,
+                              TRCOMPONENT *aComponent);
+
+    int i_unregisterTranslation(TRCOMPONENT aComponent);
+
+    const char *i_translate(TRCOMPONENT aComponent,
+                            const char *aContext,
                             const char *aSourceText,
                             const char *aComment = NULL,
                             const int   aNum = -1);
-
 };
 
Index: /trunk/src/VBox/Main/include/Wrapper.h
===================================================================
--- /trunk/src/VBox/Main/include/Wrapper.h	(revision 91311)
+++ /trunk/src/VBox/Main/include/Wrapper.h	(revision 91312)
@@ -40,5 +40,8 @@
         else \
             throw setError(E_POINTER, \
-                tr("Output argument %s points to invalid memory location (%p)"), \
+                /* Had to define VirtualBoxBase as context switcher for translation. \
+                 * Otherwise, lupdate complains about unknown context and doesn't \
+                 * include the string into translation file */ \
+                VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
                 #arg, (void *)(arg)); \
     } while (0)
Index: /trunk/src/VBox/Main/nls/ApprovedLanguages.kmk
===================================================================
--- /trunk/src/VBox/Main/nls/ApprovedLanguages.kmk	(revision 91312)
+++ /trunk/src/VBox/Main/nls/ApprovedLanguages.kmk	(revision 91312)
@@ -0,0 +1,47 @@
+# $Id$
+## @file
+# ApprovedLanguages.kmk - List of approved GUI translations
+#
+
+#
+# Copyright (C) 2007-2020 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# The list of approved GUI languages.
+VBOX_APPROVED_MAIN_LANGUAGES := \
+	bg    \
+	ca    \
+	cs    \
+	da    \
+	de    \
+	el    \
+	en    \
+	es    \
+	eu    \
+	fa    \
+	fr    \
+	hr_HR \
+	hu    \
+	id    \
+	it    \
+	ja    \
+	ko    \
+	lt    \
+	nl    \
+	pl    \
+	pt_BR \
+	ru    \
+	sl    \
+	th    \
+	tr    \
+	uk    \
+	zh_CN \
+	zh_TW
Index: /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 91312)
@@ -31,4 +31,5 @@
 #include <iprt/file.h>
 #include <iprt/ldr.h>
+#include <iprt/locale.h>
 #include <iprt/manifest.h>
 #include <iprt/param.h>
@@ -148,4 +149,7 @@
     VirtualBox         *pVirtualBox;
 #endif
+#ifdef VBOX_WITH_MAIN_NLS
+    TRCOMPONENT         pTrComponent;
+#endif
 
     RTMEMEF_NEW_AND_DELETE_OPERATORS();
@@ -194,4 +198,6 @@
     ~ExtPackInstallTask() { }
 
+    DECLARE_TRANSLATE_METHODS(ExtPackInstallTask)
+
     void handler()
     {
@@ -211,5 +217,5 @@
         if (SUCCEEDED(hrc))
         {
-            Bstr bstrDescription("Installing extension pack");
+            Bstr bstrDescription(tr("Installing extension pack"));
             hrc = ptrProgress->init(ptrExtPackFile->m->pVirtualBox,
                                     static_cast<IExtPackFile *>(ptrExtPackFile),
@@ -242,4 +248,5 @@
     explicit ExtPackUninstallTask() : ThreadTask("ExtPackUninst") { }
     ~ExtPackUninstallTask() { }
+    DECLARE_TRANSLATE_METHODS(ExtPackUninstallTask)
 
     void handler()
@@ -260,5 +267,5 @@
         if (SUCCEEDED(hrc))
         {
-            Bstr bstrDescription("Uninstalling extension pack");
+            Bstr bstrDescription(tr("Uninstalling extension pack"));
             hrc = ptrProgress->init(ptrExtPackMgr->m->pVirtualBox,
                                     static_cast<IExtPackManager *>(ptrExtPackMgr),
@@ -365,5 +372,5 @@
                                      szError, sizeof(szError), &m->hOurManifest, &hXmlFile, &m->strDigest);
     if (RT_FAILURE(vrc))
-        return initFailed(tr("%s"), szError);
+        return initFailed("%s", szError);
 
     /*
@@ -758,4 +765,5 @@
         /* pfnCreateEvent       = */ ExtPack::i_hlpCreateEvent,
         /* pfnCreateVetoEvent   = */ ExtPack::i_hlpCreateVetoEvent,
+        /* pfnTranslate         = */ ExtPack::i_hlpTranslate,
         /* pfnReserved1         = */ ExtPack::i_hlpReservedN,
         /* pfnReserved2         = */ ExtPack::i_hlpReservedN,
@@ -793,5 +801,7 @@
     RT_NOREF(a_pVirtualBox);
 #endif
-
+#ifdef VBOX_WITH_MAIN_NLS
+    m->pTrComponent                 = NULL;
+#endif
     /*
      * Make sure the SUPR3Hardened API works (ignoring errors for now).
@@ -806,4 +816,21 @@
     i_probeAndLoad();
 
+#ifdef VBOX_WITH_MAIN_NLS
+    /* register language files if exist */
+    if (m->pReg->pszNlsBaseName != NULL)
+    {
+        char szPath[RTPATH_MAX];
+        ssize_t cchOkay = RTStrPrintf2(szPath, sizeof(szPath), "%s%s%s", a_pszDir,
+                                       RTPATH_SLASH_STR "nls" RTPATH_SLASH_STR,
+                                       m->pReg->pszNlsBaseName);
+        if (cchOkay > 0)
+        {
+            rc = VirtualBoxTranslator::registerTranslation(szPath, false, &m->pTrComponent);
+            if (RT_FAILURE(rc))
+                m->pTrComponent = NULL;
+        }
+    }
+#endif
+
     autoInitSpan.setSucceeded();
     return S_OK;
@@ -841,4 +868,8 @@
         VBoxExtPackFreeDesc(&m->Desc);
 
+#ifdef VBOX_WITH_MAIN_NLS
+        if (m->pTrComponent != NULL)
+            VirtualBoxTranslator::unregisterTranslation(m->pTrComponent);
+#endif
         delete m;
         m = NULL;
@@ -1975,4 +2006,31 @@
 
     return pEvent.queryInterfaceTo(ppEventOut);
+}
+
+
+/*static*/ DECLCALLBACK(const char *)
+ExtPack::i_hlpTranslate(PCVBOXEXTPACKHLP pHlp,
+                        const char *pszComponent,
+                        const char *pszSourceText,
+                        const char *pszComment /* = NULL */,
+                        const int   iNum /* = -1 */)
+{
+    /*
+     * Validate the input and get our bearings.
+     */
+    AssertPtrReturn(pHlp, pszSourceText);
+    AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, pszSourceText);
+    ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+    AssertPtrReturn(m, pszSourceText);
+
+#ifdef VBOX_WITH_MAIN_NLS
+    return VirtualBoxTranslator::translate(m->pTrComponent, pszComponent,
+                                           pszSourceText,  pszComment, iNum);
+#else
+    NOREF(pszComponent);
+    NOREF(pszComment);
+    NOREF(iNum);
+    return pszSourceText;
+#endif
 }
 
Index: /trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp	(revision 91312)
@@ -310,5 +310,9 @@
     if (aLogIt)
     {
-        strText = trSource(aText);
+#ifdef VBOX_WITH_MAIN_NLS
+        strText = VirtualBoxTranslator::trSource(aText);
+#else
+        strText = aText;
+#endif
         va_list va2;
         va_copy(va2, aArgs);
Index: /trunk/src/VBox/Main/src-all/VirtualBoxTranslator.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/VirtualBoxTranslator.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-all/VirtualBoxTranslator.cpp	(revision 91312)
@@ -67,5 +67,6 @@
     : util::RWLockHandle(VBoxLockingClass::LOCKCLASS_TRANSLATOR)
     , m_cInstanceRefs(0)
-    , m_pTranslator(NULL)
+    , m_pDefaultComponent(NULL)
+    , m_strLanguage("C")
     , m_hStrCache(NIL_RTSTRCACHE)
 {
@@ -92,8 +93,14 @@
         g_idxTls = NIL_RTTLS;
     }
-    if (m_pTranslator)
-    {
-        delete m_pTranslator;
-        m_pTranslator = NULL;
+
+    m_pDefaultComponent = NULL;
+
+    for (TranslatorList::iterator it = m_lTranslators.begin();
+         it != m_lTranslators.end();
+         ++it)
+    {
+        if (it->pTranslator != NULL)
+            delete it->pTranslator;
+        it->pTranslator = NULL;
     }
     if (m_hStrCache != NIL_RTSTRCACHE)
@@ -164,5 +171,5 @@
 /**
  * Release translator reference previous obtained via instance() or
- * i_instance().
+ * tryinstance().
  */
 void VirtualBoxTranslator::release()
@@ -234,43 +241,55 @@
     if (RT_SUCCESS(rc))
     {
-        if (strcmp(pszLang, "C") != 0)
-        {
-            /* Construct the base filename for the translations: */
-            char szNlsPath[RTPATH_MAX];
-            rc = RTPathAppPrivateNoArch(szNlsPath, sizeof(szNlsPath));
-            if (RT_SUCCESS(rc))
-                rc = RTPathAppend(szNlsPath, sizeof(szNlsPath), "nls" RTPATH_SLASH_STR "VirtualBoxAPI_");
-            if (RT_SUCCESS(rc))
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+        m_strLanguage = pszLang;
+
+        for (TranslatorList::iterator it = m_lTranslators.begin();
+             it != m_lTranslators.end();
+             ++it)
+        {
+            /* ignore errors from particular translator allowing the use of others */
+            i_loadLanguageForComponent(&(*it), pszLang);
+        }
+    }
+    return rc;
+}
+
+
+int VirtualBoxTranslator::i_loadLanguageForComponent(TranslatorComponent *aComponent, const char *aLang)
+{
+    AssertReturn(aComponent, VERR_INVALID_PARAMETER);
+    int rc;
+    if (strcmp(aLang, "C") != 0)
+    {
+        /* Construct the base filename for the translations: */
+        char szNlsPath[RTPATH_MAX];
+        /* Try load language file on form 'VirtualBoxAPI_ll_CC.qm' if it exists
+           where 'll_CC' could for example be 'en_US' or 'de_CH': */
+        ssize_t cchOkay = RTStrPrintf2(szNlsPath, sizeof(szNlsPath), "%s_%s.qm",
+                                       aComponent->strPath.c_str(), aLang);
+        if (cchOkay > 0)
+            rc = i_setLanguageFile(aComponent, szNlsPath);
+        else
+            rc = VERR_FILENAME_TOO_LONG;
+        if (RT_FAILURE(rc))
+        {
+            /* No luck, drop the country part, i.e. 'VirtualBoxAPI_de.qm' or 'VirtualBoxAPI_en.qm': */
+            const char *pszDash = strchr(aLang, '_');
+            if (pszDash && pszDash != aLang)
             {
-                size_t const cchNlsBase = strlen(szNlsPath);
-
-                /* Try load language file on form 'VirtualBoxAPI_ll_CC.qm' if it exists
-                   where 'll_CC' could for example be 'en_US' or 'de_CH': */
-                ssize_t cchOkay = RTStrPrintf2(&szNlsPath[cchNlsBase], sizeof(szNlsPath) - cchNlsBase, "%s.qm", pszLang);
+                cchOkay = RTStrPrintf2(szNlsPath, sizeof(szNlsPath), "%s_%.*s.qm",
+                                       aComponent->strPath.c_str(), pszDash - aLang, aLang);
                 if (cchOkay > 0)
-                    rc = i_setLanguageFile(szNlsPath);
-                else
-                    rc = VERR_FILENAME_TOO_LONG;
-                if (RT_FAILURE(rc))
-                {
-                    /* No luck, drop the country part, i.e. 'VirtualBoxAPI_de.qm' or 'VirtualBoxAPI_en.qm': */
-                    const char *pszDash = strchr(pszLang, '_');
-                    if (pszDash && pszDash != pszLang)
-                    {
-                        cchOkay = RTStrPrintf2(&szNlsPath[cchNlsBase], sizeof(szNlsPath) - cchNlsBase, "%.*s.qm",
-                                               pszDash - pszLang, pszLang);
-                        if (cchOkay > 0)
-                            rc = i_setLanguageFile(szNlsPath);
-                    }
-                }
+                    rc = i_setLanguageFile(aComponent, szNlsPath);
             }
         }
-        else
-        {
-            /* No translator needed for 'C': */
-            AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-            delete m_pTranslator;
-            m_pTranslator = NULL;
-        }
+    }
+    else
+    {
+        /* No translator needed for 'C' */
+        delete aComponent->pTranslator;
+        aComponent->pTranslator = NULL;
+        rc = VINF_SUCCESS;
     }
     return rc;
@@ -278,6 +297,8 @@
 
 
-int VirtualBoxTranslator::i_setLanguageFile(const char *aFileName)
-{
+int VirtualBoxTranslator::i_setLanguageFile(TranslatorComponent *aComponent, const char *aFileName)
+{
+    AssertReturn(aComponent, VERR_INVALID_PARAMETER);
+
     int rc = m_rcCache;
     if (m_hStrCache != NIL_RTSTRCACHE)
@@ -291,10 +312,7 @@
             if (RT_SUCCESS(rc))
             {
-                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-                if (m_pTranslator)
-                    delete m_pTranslator;
-                m_pTranslator     = pNewTranslator;
-                m_strLangFileName = aFileName;
+                if (aComponent->pTranslator)
+                    delete aComponent->pTranslator;
+                aComponent->pTranslator = pNewTranslator;
             }
             else
@@ -310,12 +328,100 @@
 
 
-com::Utf8Str VirtualBoxTranslator::i_languageFile()
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-    return m_strLangFileName;
-}
-
-
-const char *VirtualBoxTranslator::translate(const char *aContext,
+int VirtualBoxTranslator::registerTranslation(const char *aTranslationPath,
+                                              bool aDefault,
+                                              TRCOMPONENT *aComponent)
+{
+    VirtualBoxTranslator *pCurrInstance = VirtualBoxTranslator::tryInstance();
+    int rc = VERR_GENERAL_FAILURE;
+    if (pCurrInstance != NULL)
+    {
+        rc = pCurrInstance->i_registerTranslation(aTranslationPath, aDefault, aComponent);
+        pCurrInstance->release();
+    }
+    return rc;
+}
+
+
+int VirtualBoxTranslator::i_registerTranslation(const char *aTranslationPath,
+                                                bool aDefault,
+                                                TRCOMPONENT *aComponent)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+    TranslatorComponent *pComponent;
+    for (TranslatorList::iterator it = m_lTranslators.begin();
+         it != m_lTranslators.end();
+         ++it)
+    {
+        if (it->strPath == aTranslationPath)
+        {
+            pComponent = &(*it);
+            if (aDefault)
+                m_pDefaultComponent = pComponent;
+            *aComponent = (TRCOMPONENT)pComponent;
+            return VINF_SUCCESS;
+        }
+    }
+
+    try
+    {
+        m_lTranslators.push_back(TranslatorComponent());
+        pComponent = &m_lTranslators.back();
+    }
+    catch(std::bad_alloc &)
+    {
+        return VERR_NO_MEMORY;
+    }
+
+    pComponent->strPath = aTranslationPath;
+    if (aDefault)
+        m_pDefaultComponent = pComponent;
+    *aComponent = (TRCOMPONENT)pComponent;
+    /* ignore the error during loading because path
+     * could contain no translation for current language */
+    i_loadLanguageForComponent(pComponent, m_strLanguage.c_str());
+    return VINF_SUCCESS;
+}
+
+
+int VirtualBoxTranslator::unregisterTranslation(TRCOMPONENT aComponent)
+{
+    VirtualBoxTranslator *pCurrInstance = VirtualBoxTranslator::tryInstance();
+    int rc = VERR_GENERAL_FAILURE;
+    if (pCurrInstance != NULL)
+    {
+        rc = pCurrInstance->i_unregisterTranslation(aComponent);
+        pCurrInstance->release();
+    }
+    return rc;
+}
+
+
+int VirtualBoxTranslator::i_unregisterTranslation(TRCOMPONENT aComponent)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    TranslatorComponent *pComponent = (TranslatorComponent *)aComponent;
+
+    if (pComponent == m_pDefaultComponent)
+        m_pDefaultComponent = NULL;
+
+    for (TranslatorList::iterator it = m_lTranslators.begin();
+         it != m_lTranslators.end();
+         ++it)
+    {
+        if (&(*it) == pComponent)
+        {
+            delete pComponent->pTranslator;
+            m_lTranslators.erase(it);
+            return VINF_SUCCESS;
+        }
+    }
+
+    return VERR_NOT_FOUND;
+}
+
+
+const char *VirtualBoxTranslator::translate(TRCOMPONENT aComponent,
+                                            const char *aContext,
                                             const char *aSourceText,
                                             const char *aComment,
@@ -326,5 +432,6 @@
     if (pCurrInstance != NULL)
     {
-        pszTranslation = pCurrInstance->i_translate(aContext, aSourceText, aComment, aNum);
+        pszTranslation = pCurrInstance->i_translate(aComponent, aContext,
+                                                    aSourceText, aComment, aNum);
         pCurrInstance->release();
     }
@@ -359,5 +466,6 @@
 
 
-const char *VirtualBoxTranslator::i_translate(const char *aContext,
+const char *VirtualBoxTranslator::i_translate(TRCOMPONENT aComponent,
+                                              const char *aContext,
                                               const char *aSourceText,
                                               const char *aComment,
@@ -365,8 +473,14 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-    if (!m_pTranslator)
+
+    TranslatorComponent *pComponent = (TranslatorComponent *)aComponent;
+    if (pComponent == NULL)
+        pComponent = m_pDefaultComponent;
+
+    if (   pComponent == NULL
+        || pComponent->pTranslator == NULL)
         return aSourceText;
-    const char *pszTranslation = m_pTranslator->translate(aContext, aSourceText, aComment, aNum);
-    alock.release();
+
+    const char *pszTranslation = pComponent->pTranslator->translate(aContext, aSourceText, aComment, aNum);
 
     LastTranslation *pEntry = getTlsEntry();
@@ -374,5 +488,7 @@
     {
         pEntry->first = pszTranslation;
-        pEntry->second = aSourceText;
+        pEntry->second = m_hStrCache != NIL_RTSTRCACHE ?
+                            RTStrCacheEnter(m_hStrCache, aSourceText) :
+                            aSourceText;
     }
 
Index: /trunk/src/VBox/Main/src-client/SessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/SessionImpl.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-client/SessionImpl.cpp	(revision 91312)
@@ -38,5 +38,5 @@
     do { \
         if (mState != SessionState_Locked) \
-            return setError(E_UNEXPECTED, tr ("The session is not locked (session state: %s)"), \
+            return setError(E_UNEXPECTED, Session::tr("The session is not locked (session state: %s)"), \
                             Global::stringifySessionState(mState)); \
     } while (0)
Index: /trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp	(revision 91312)
@@ -29,4 +29,5 @@
 #include <iprt/thread.h>
 #include <iprt/critsect.h>
+#include <iprt/path.h>
 #include <iprt/semaphore.h>
 #include <iprt/cpp/utils.h>
@@ -189,4 +190,5 @@
         AssertMsg(s_cUnnecessaryAtlModuleLocks == 1, ("%d\n", s_cUnnecessaryAtlModuleLocks));
 
+        int vrc;
 #ifdef VBOX_WITH_MAIN_NLS
         /* Create the translator singelton (must work) and try load translations (non-fatal). */
@@ -194,14 +196,26 @@
         if (mData.m_pVBoxTranslator == NULL)
             throw setError(VBOX_E_IPRT_ERROR, tr("Failed to create translator instance"));
-        rc = i_reloadApiLanguage();
-        if (SUCCEEDED(rc))
-            i_registerEventListener(); /* for updates */
+
+        char szNlsPath[RTPATH_MAX];
+        rc = RTPathAppPrivateNoArch(szNlsPath, sizeof(szNlsPath));
+        if (RT_SUCCESS(rc))
+            rc = RTPathAppend(szNlsPath, sizeof(szNlsPath), "nls" RTPATH_SLASH_STR "VirtualBoxAPI");
+
+        vrc = mData.m_pVBoxTranslator->registerTranslation(szNlsPath, true, &mData.m_pTrComponent);
+        if (RT_SUCCESS(vrc))
+        {
+            rc = i_reloadApiLanguage();
+            if (SUCCEEDED(rc))
+                i_registerEventListener(); /* for updates */
+            else
+                LogRelFunc(("i_reloadApiLanguage failed: %Rhrc\n", rc));
+        }
         else
-            LogRelFunc(("i_reloadApiLanguage failed: %Rhrc\n", rc));
+            LogRelFunc(("Register translation failed: %Rrc\n", vrc));
 #endif
         /* Setting up the VBoxSVC watcher thread. If anything goes wrong here it
          * is not considered important enough to cause any sort of visible
          * failure. The monitoring will not be done, but that's all. */
-        int vrc = RTSemEventCreate(&mData.m_SemEvWatcher);
+        vrc = RTSemEventCreate(&mData.m_SemEvWatcher);
         if (RT_FAILURE(vrc))
         {
@@ -563,4 +577,5 @@
         mData.m_pVBoxTranslator->release();
         mData.m_pVBoxTranslator = NULL;
+        mData.m_pTrComponent = NULL;
     }
 #endif
Index: /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 91312)
@@ -63,5 +63,5 @@
 /////////////////////////////////////////////////////////////////////////////
 
-struct MachineCloneVMPrivate : public VirtualBoxTranslatable
+struct MachineCloneVMPrivate
 {
     MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine,
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 91311)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 91312)
@@ -299,4 +299,5 @@
 #ifdef VBOX_WITH_MAIN_NLS
         , pVBoxTranslator(NULL)
+        , pTrComponent(NULL)
 #endif
 #if defined(RT_OS_WINDOWS) && defined(VBOXSVC_WITH_CLIENT_WATCHER)
@@ -410,4 +411,5 @@
 #ifdef VBOX_WITH_MAIN_NLS
     VirtualBoxTranslator               *pVBoxTranslator;
+    TRCOMPONENT                         pTrComponent;
 #endif
 #if defined(RT_OS_WINDOWS) && defined(VBOXSVC_WITH_CLIENT_WATCHER)
@@ -581,4 +583,59 @@
         unconst(m->pAutostartDb) = new AutostartDb;
 
+        /* create the system properties object, someone may need it too */
+        rc = unconst(m->pSystemProperties).createObject();
+        if (SUCCEEDED(rc))
+            rc = m->pSystemProperties->init(this);
+        ComAssertComRCThrowRC(rc);
+
+        rc = m->pSystemProperties->i_loadSettings(m->pMainConfigFile->systemProperties);
+        if (FAILED(rc)) throw rc;
+#ifdef VBOX_WITH_MAIN_NLS
+        m->pVBoxTranslator = VirtualBoxTranslator::instance();
+        /* Do not throw an exception on language errors.
+         * Just do not use translation. */
+        if (m->pVBoxTranslator)
+        {
+
+            char szNlsPath[RTPATH_MAX];
+            rc = RTPathAppPrivateNoArch(szNlsPath, sizeof(szNlsPath));
+            if (RT_SUCCESS(rc))
+                rc = RTPathAppend(szNlsPath, sizeof(szNlsPath), "nls" RTPATH_SLASH_STR "VirtualBoxAPI");
+
+            int vrc = m->pVBoxTranslator->registerTranslation(szNlsPath, true, &m->pTrComponent);
+            if (RT_SUCCESS(vrc))
+            {
+                com::Utf8Str strLocale;
+                HRESULT hrc = m->pSystemProperties->getLanguageId(strLocale);
+                if (SUCCEEDED(hrc))
+                {
+                    vrc = m->pVBoxTranslator->i_loadLanguage(strLocale.c_str());
+                    if (RT_FAILURE(vrc))
+                    {
+                        hrc = Global::vboxStatusCodeToCOM(vrc);
+                        LogRel(("Load language failed (%Rhrc).\n", hrc));
+                    }
+                }
+                else
+                {
+                    LogRel(("Getting language settings failed (%Rhrc).\n", hrc));
+                    m->pVBoxTranslator->release();
+                    m->pVBoxTranslator = NULL;
+                    m->pTrComponent = NULL;
+                }
+            }
+            else
+            {
+                HRESULT hrc = Global::vboxStatusCodeToCOM(vrc);
+                LogRel(("Register translation failed (%Rhrc).\n", hrc));
+                m->pVBoxTranslator->release();
+                m->pVBoxTranslator = NULL;
+                m->pTrComponent = NULL;
+            }
+        }
+        else
+            LogRel(("Translator creation failed.\n"));
+#endif
+
 #ifdef VBOX_WITH_EXTPACK
         /*
@@ -591,40 +648,4 @@
         if (FAILED(rc))
             throw rc;
-#endif
-
-        /* create the system properties object, someone may need it too */
-        rc = unconst(m->pSystemProperties).createObject();
-        if (SUCCEEDED(rc))
-            rc = m->pSystemProperties->init(this);
-        ComAssertComRCThrowRC(rc);
-
-        rc = m->pSystemProperties->i_loadSettings(m->pMainConfigFile->systemProperties);
-        if (FAILED(rc)) throw rc;
-#ifdef VBOX_WITH_MAIN_NLS
-        m->pVBoxTranslator = VirtualBoxTranslator::instance();
-        /* Do not throw an exception on language errors.
-         * Just do not use translation. */
-        if (m->pVBoxTranslator)
-        {
-            com::Utf8Str strLocale;
-            HRESULT hrc = m->pSystemProperties->getLanguageId(strLocale);
-            if (SUCCEEDED(hrc))
-            {
-                int vrc = m->pVBoxTranslator->i_loadLanguage(strLocale.c_str());
-                if (RT_FAILURE(vrc))
-                {
-                    hrc = Global::vboxStatusCodeToCOM(vrc);
-                    LogRel(("Load language failed (%Rhrc).\n", hrc));
-                }
-            }
-            else
-            {
-                LogRel(("Getting language settings failed (%Rhrc).\n", hrc));
-                m->pVBoxTranslator->release();
-                m->pVBoxTranslator = NULL;
-            }
-        }
-        else
-            LogRel(("Translator creation failed.\n"));
 #endif
         /* guest OS type objects, needed by machines */
Index: /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def
===================================================================
--- /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 91311)
+++ /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 91312)
@@ -1301,4 +1301,5 @@
     RTLogWriteStdOut
     RTLogWriteUser
+    RTLocaleQueryNormalizedBaseLocaleName
     RTManifestCreate
     RTManifestDup
@@ -2056,4 +2057,5 @@
     RTUniFree
     RTUriParse
+    RTUtf16BigToUtf8ExTag
     RTUtf16CalcLatin1Len
     RTUtf16CalcLatin1LenEx
Index: /trunk/tools/bin/gen-slickedit-workspace.sh
===================================================================
--- /trunk/tools/bin/gen-slickedit-workspace.sh	(revision 91311)
+++ /trunk/tools/bin/gen-slickedit-workspace.sh	(revision 91312)
@@ -632,5 +632,5 @@
                                  const int   aNum = -1) \
     { \
-        return VirtualBoxTranslatable::translate(#cls, aSourceText, aComment, aNum); \
+        return VirtualBoxTranslator::translate(#cls, aSourceText, aComment, aNum); \
     }
 #define DECLARE_COMMON_CLASS_METHODS(cls) \
