diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/XSD_Definitions_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/XSD_Definitions_e.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..ad455bff2bd09a1a90e225e110d5528b627f80ba
--- /dev/null
+++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/XSD_Definitions_e.ttcn
@@ -0,0 +1,124 @@
+/*******************************************************************************
+* Copyright (c) 2000-2018 Ericsson Telecom AB
+*
+* XSD to TTCN-3 Translator
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+*
+* Contributors:
+*   Baranyi, Botond
+*
+*******************************************************************************/
+//
+//  File:          XSD_Definitions.ttcn
+//  Description:
+//  References:
+//  Rev:
+//  Prodnr:
+//  Updated:
+//  Contact:       http://ttcn.ericsson.se
+//
+////////////////////////////////////////////////////////////////////////////////
+//     Modification header(s):
+//-----------------------------------------------------------------------------
+//  Modified by:
+//  Modification date:
+//  Description:
+//  Modification contact:
+//------------------------------------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+
+
+module XSD_Definitions_e {
+
+
+import from XSD all;
+
+
+////////////////////////////////////////////////////////////////////////////////
+//	Generated from file(s):
+//	- substitution_group_one.xsd
+//			/* xml version = "1.0" */
+//			/* targetnamespace = "http://www.somewhere.com/one" */
+////////////////////////////////////////////////////////////////////////////////
+group http_www_somewhere_com_one {
+
+
+import from XSD all;
+
+
+type record HeadType
+{
+	XSD.String str optional
+}
+with {
+  variant "abstract";
+  variant (str) "attribute";
+};
+
+
+type union Head_group
+{
+	HeadType head,
+	Extended extended
+}
+with {
+  variant "untagged";
+  variant (head) "name as capitalized";
+  variant (head) "form as qualified";
+  variant (head) "abstract";
+  variant (extended) "name as capitalized";
+  variant (extended) "namespace as 'http://www.somewhere.com/two' prefix 'two'";
+};
+
+
+}
+with {
+  encode "XML";
+  variant "namespace as 'http://www.somewhere.com/one' prefix 'one'";
+  variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
+  variant "elementFormQualified";
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//	Generated from file(s):
+//	- substitution_group_two.xsd
+//			/* xml version = "1.0" */
+//			/* targetnamespace = "http://www.somewhere.com/two" */
+////////////////////////////////////////////////////////////////////////////////
+group http_www_somewhere_com_two {
+
+
+import from XSD all;
+
+
+type ExtendedType Extended
+with {
+  variant "element";
+};
+
+
+type record ExtendedType
+{
+	XSD.String str optional,
+	XSD.Integer num
+}
+with {
+  variant (str) "attribute";
+};
+
+
+}
+with {
+  encode "XML";
+  variant "namespace as 'http://www.somewhere.com/two' prefix 'two'";
+  variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
+  variant "elementFormQualified";
+}
+
+
+}
diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn
index 901a94c0a2cf95f18c317f96ffa690d78e9cb711..1663a0807792b73b8fcb1a8bb5224b5a7c042a41 100644
--- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn
+++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn
@@ -66,6 +66,7 @@ with {
   variant (subsgroup) "form as qualified";
   variant (subsgroup) "abstract";
   variant (replace_) "name as 'replace'";
+  variant (replace_) "namespace as 'www.example.org/substitutiongroup/ref' prefix 'this'";
 };
 
 
diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest.prj b/regression_test/XML/XmlWorkflow/src/xmlTest.prj
index 4da17360f68092437fba7cefba88dce0ac12476b..c268be59e4837f7dea115570bd0a374f464e95c1 100644
--- a/regression_test/XML/XmlWorkflow/src/xmlTest.prj
+++ b/regression_test/XML/XmlWorkflow/src/xmlTest.prj
@@ -144,6 +144,8 @@
                 <File path="../xsd/attrib_enum.xsd" />
                 <File path="../xsd/substitutiongroup_main.xsd" />
                 <File path="../xsd/substitutiongroup_ref.xsd" />
+                <File path="../xsd/substitution_group_one.xsd" />
+                <File path="../xsd/substitution_group_two.xsd" />
 		<File path="../xsd/simpletype_base.xsd" />
 		<File path="../xsd/type_substitution.xsd" />
 		<File path="../xsd/type_substitution_chain.xsd" />
@@ -389,6 +391,7 @@
 		<File path="../XmlTest_expectedTtcns/www_example_org_attrib_enum_e.ttcn" />
 		<File path="../XmlTest_expectedTtcns/www_example_org_substitutiongroup_ref_e.ttcn" />
 		<File path="../XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn" />
+		<File path="../XmlTest_expectedTtcns/XSD_Definitions_e.ttcn" />
 	        <File path="../XmlTest_expectedTtcns/www_example_org_simpletype_base_e.ttcn" />
 	        <File path="../XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn" />
 	        <File path="../XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn" />
diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn
index d4206c68ac7463415bd4f51dfb5674ea38c901f7..090bbf6b02881bb25482fedb393c573f4231d878 100644
--- a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn
+++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn
@@ -2613,6 +2613,18 @@ group Elements{
   testcase tc_element_nillable_RemarkNillable_nilTrue_encDec() runs on xmlTest_CT {
     f_encDecTest_RemarkNillable2();
   }//tc_
+  
+  
+  testcase tc_substitution_group_merged() runs on xmlTest_CT {
+    f_shellCommandWithVerdict(xsd2ttcn_command & " -o substitution_group_one.xsd substitution_group_two.xsd",
+      "", c_shell_successWithoutWarningAndError);
+
+    if(getverdict == pass) {
+      f_compareFiles(
+        "XSD_Definitions_e.ttcn",
+        "XSD_Definitions.ttcn", c_numOfDiff);
+    }
+  }
 
 }//Element
 
@@ -2888,6 +2900,7 @@ control {
   execute(tc_element_nillable_RemarkNillable_nilFalse_encDec());
   execute(tc_element_nillable_RemarkNillable_nilTrue_encDec());
 
+  execute(tc_substitution_group_merged());
 }
 
 } with {
diff --git a/regression_test/XML/XmlWorkflow/xsd/substitution_group_one.xsd b/regression_test/XML/XmlWorkflow/xsd/substitution_group_one.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..3ae9acac51a090c3223342f5ad19e6e855fbc787
--- /dev/null
+++ b/regression_test/XML/XmlWorkflow/xsd/substitution_group_one.xsd
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+        xmlns:one="http://www.somewhere.com/one"
+        targetNamespace="http://www.somewhere.com/one"
+        version="3.1.1" elementFormDefault="qualified">
+  <element name="Head" type="one:HeadType" abstract="true"/>
+  <complexType name="HeadType" abstract="true">
+    <attribute name="str" type="string" use="optional"/>
+  </complexType>
+</schema>
diff --git a/regression_test/XML/XmlWorkflow/xsd/substitution_group_two.xsd b/regression_test/XML/XmlWorkflow/xsd/substitution_group_two.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..e2333e1d664ae8fb96f0cb8a740e94e852166280
--- /dev/null
+++ b/regression_test/XML/XmlWorkflow/xsd/substitution_group_two.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<xs:schema targetNamespace="http://www.somewhere.com/two"
+        xmlns:two="http://www.somewhere.com/two"
+        xmlns:one="http://www.somewhere.com/one"
+        xmlns:xs="http://www.w3.org/2001/XMLSchema"
+        version="3.1.1" elementFormDefault="qualified">
+  <xs:import namespace="http://www.somewhere.com/one" schemaLocation="substitution_group_one.xsd"/>
+  <xs:element name="Extended" type="two:ExtendedType"
+        substitutionGroup="one:Head"/>
+  <xs:complexType name="ExtendedType">
+    <xs:complexContent>
+      <xs:extension base="one:HeadType">
+        <xs:sequence>
+          <xs:element name="num" type="xs:integer"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+</xs:schema>
diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc
index a9e711262d089ea328fcd356d1f3e6b09722cccb..2d3ade34bb01c35c41dd654f41c22181fbfa6d9c 100644
Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ
diff --git a/xsdconvert/ComplexType.cc b/xsdconvert/ComplexType.cc
index d1cfcab8a78819e66771851e0e6af3fe5449f72e..8e149eab1e7ca6b2f559ef856dc9bdac65d765f1 100644
--- a/xsdconvert/ComplexType.cc
+++ b/xsdconvert/ComplexType.cc
@@ -22,6 +22,7 @@
 #include "TTCN3ModuleInventory.hh"
 #include "Annotation.hh"
 #include "Constant.hh"
+#include "converter.hh"
 
 #include <assert.h>
 
@@ -2357,6 +2358,31 @@ void ComplexType::addSubstitution(SimpleType * st){
         element->addVariant(V_block);
       }
     }
+    if (st->getModule()->getTargetNamespace() != module->getTargetNamespace() &&
+        st->getModule()->getTargetNamespace() != "NoTargetNamespace") {
+      element->addVariant(V_namespaceAs, st->getModule()->getTargetNamespace());
+    }
+    if (!o_flag_used && st->getModule() != module &&
+        !isBuiltInType(st->getType().convertedValue)) {
+      bool import_found = false;
+      for (List<const TTCN3Module*>::iterator imp = module->getImportedModules().begin();
+           imp != module->getImportedModules().end(); ++imp) {
+        if (imp->Data == st->getModule()) {
+          import_found = true;
+          break;
+        }
+      }
+      if (!import_found) {
+        printWarning(st->getModule()->getSchemaname(), st->getName().convertedValue,
+          Mstring("Type `") + st->getName().convertedValue + Mstring("' is used "
+          "in a substitution group in module `") + module->getModulename() +
+          Mstring("', which does not import the type's module. This may lead to "
+          "errors in the generated code. For a safe solution, please use the "
+          "single module command line option (-o) or disable element "
+          "substitution (-g)."));
+        TTCN3ModuleInventory::incrNumWarnings();
+      }
+    }
   }
 
   element->setNameValue(st->getName().convertedValue);
diff --git a/xsdconvert/TTCN3Module.cc b/xsdconvert/TTCN3Module.cc
index e89c4bb1029756a93377cad6d3430ddfe9b2bb37..50d9aa285b89dbaa59713ae231d553f0ae1c5291 100644
--- a/xsdconvert/TTCN3Module.cc
+++ b/xsdconvert/TTCN3Module.cc
@@ -38,6 +38,8 @@
 extern bool e_flag_used;
 extern bool z_flag_used;
 
+unsigned int TTCN3Module::static_const_counter = 1;
+
 TTCN3Module::TTCN3Module(const char * a_filename, XMLParser * a_parser)
 : parser(a_parser)
 , schemaname()
@@ -272,13 +274,13 @@ void TTCN3Module::generate_TTCN3_fileinfo(FILE * file) {
 
 void TTCN3Module::generate_TTCN3_modulestart(FILE * file) {
   fprintf(file,
-    "module %s {\n"
+    "%s %s {\n"
     "\n"
     "\n"
     "import from XSD all;\n"
     "\n"
     "\n",
-    modulename.c_str()
+    o_flag_used ? "group" : "module", modulename.c_str()
     );
 }
 
diff --git a/xsdconvert/TTCN3Module.hh b/xsdconvert/TTCN3Module.hh
index 5344f65b5d5ee65b2aa78e039ef41c6c77010865..f9563e74fb148ebbaff8f73707c7a44cdc8a5e16 100644
--- a/xsdconvert/TTCN3Module.hh
+++ b/xsdconvert/TTCN3Module.hh
@@ -19,6 +19,7 @@
 #include "GeneralTypes.hh"
 #include "GeneralFunctions.hh"
 #include "TTCN3ModuleInventory.hh"
+#include "converter.hh"
 
 class TTCN3ModuleInventory;
 class RootType;
@@ -98,6 +99,8 @@ class TTCN3Module {
   bool moduleNotIntoNameConversion;
   
   unsigned int const_counter;
+  
+  static unsigned int static_const_counter;
 
   TTCN3Module & operator=(const TTCN3Module &); // not implemented
   TTCN3Module(const TTCN3Module &); // not implemented
@@ -271,11 +274,16 @@ public:
   friend bool compareModules(TTCN3Module * lhs, TTCN3Module * rhs);
   
   unsigned int getConstCounter() {
-    return const_counter;
+    return o_flag_used ? static_const_counter : const_counter;
   }
   
   void increaseConstCounter() {
-    ++const_counter;
+    if (o_flag_used) {
+      ++static_const_counter;
+    }
+    else {
+      ++const_counter;
+    }
   }
 
   void dump() const;
diff --git a/xsdconvert/TTCN3ModuleInventory.cc b/xsdconvert/TTCN3ModuleInventory.cc
index 8424dc00cc05a59af90673f6f7d9da38f9943888..f2cbdfc76cebeb11a99febd2a30ee7eed07c5146 100644
--- a/xsdconvert/TTCN3ModuleInventory.cc
+++ b/xsdconvert/TTCN3ModuleInventory.cc
@@ -237,6 +237,32 @@ void TTCN3ModuleInventory::nameConversion() {
 }
 
 void TTCN3ModuleInventory::moduleGeneration() {
+  FILE * file = NULL;
+  if (o_flag_used) {
+    file = fopen("XSD_Definitions.ttcn", "w");
+    if (file == NULL) {
+      perror("Cannot open file XSD_Definitions.ttcn for writing.");
+      ++num_errors;
+      return;
+    }
+    generate_TTCN3_header(file, "XSD_Definitions");
+    fprintf(file,
+      "//     Modification header(s):\n"
+      "//-----------------------------------------------------------------------------\n"
+      "//  Modified by:\n"
+      "//  Modification date:\n"
+      "//  Description:\n"
+      "//  Modification contact:\n"
+      "//------------------------------------------------------------------------------\n"
+      "////////////////////////////////////////////////////////////////////////////////\n"
+      "\n"
+      "\n"
+      "module XSD_Definitions {\n"
+      "\n"
+      "\n"
+      "import from XSD all;\n");
+  }
+  
   for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
     if (module->Data->isnotIntoFile()) {
       continue;
@@ -261,12 +287,14 @@ void TTCN3ModuleInventory::moduleGeneration() {
     }
 
     Mstring filename_s = module->Data->getModulename() + ".ttcn";
-    FILE * file = fopen(filename_s.c_str(), "w");
-    if (file == NULL) {
-      Mstring cannot_write("Cannot write file ");
-      perror((cannot_write + filename_s).c_str());
-      ++num_errors;
-      return;
+    if (!o_flag_used) {
+      file = fopen(filename_s.c_str(), "w");
+      if (file == NULL) {
+        Mstring cannot_write("Cannot write file ");
+        perror((cannot_write + filename_s).c_str());
+        ++num_errors;
+        return;
+      }
     }
 #ifndef NDEBUG
     // In debug mode, set the output stream to unbuffered.
@@ -274,7 +302,14 @@ void TTCN3ModuleInventory::moduleGeneration() {
     setvbuf(file, NULL, _IONBF, 0);
 #endif
 
-    generate_TTCN3_header(file, module->Data->getModulename().c_str());
+    if (!o_flag_used) {
+      generate_TTCN3_header(file, module->Data->getModulename().c_str());
+    }
+    
+    if (o_flag_used) {
+      fprintf(file, "\n\n"
+        "////////////////////////////////////////////////////////////////////////////////\n");
+    }
 
     fprintf(file, "//\tGenerated from file(s):\n");
 
@@ -283,25 +318,31 @@ void TTCN3ModuleInventory::moduleGeneration() {
         module2->Data->generate_TTCN3_fileinfo(file);
       }
     }
-
+    
     fprintf(file,
-      "////////////////////////////////////////////////////////////////////////////////\n"
-      "//     Modification header(s):\n"
-      "//-----------------------------------------------------------------------------\n"
-      "//  Modified by:\n"
-      "//  Modification date:\n"
-      "//  Description:\n"
-      "//  Modification contact:\n"
-      "//------------------------------------------------------------------------------\n"
-      "////////////////////////////////////////////////////////////////////////////////\n"
-      "\n"
-      "\n");
+      "////////////////////////////////////////////////////////////////////////////////\n");
+
+    if (!o_flag_used) {
+      fprintf(file,
+        "//     Modification header(s):\n"
+        "//-----------------------------------------------------------------------------\n"
+        "//  Modified by:\n"
+        "//  Modification date:\n"
+        "//  Description:\n"
+        "//  Modification contact:\n"
+        "//------------------------------------------------------------------------------\n"
+        "////////////////////////////////////////////////////////////////////////////////\n"
+        "\n"
+        "\n");
+    }
 
     module->Data->generate_TTCN3_modulestart(file);
 
-    for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
-      if (module2->Data->getModulename() == module->Data->getModulename()) {
-        module2->Data->generate_TTCN3_import_statements(file);
+    if (!o_flag_used) {
+      for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
+        if (module2->Data->getModulename() == module->Data->getModulename()) {
+          module2->Data->generate_TTCN3_import_statements(file);
+        }
       }
     }
 
@@ -318,8 +359,20 @@ void TTCN3ModuleInventory::moduleGeneration() {
 
     module->Data->generate_with_statement(file, used_namespaces);
 
-    if (!q_flag_used) fprintf(stderr, "Notify: File '%s' was generated.\n", filename_s.c_str());
+    if (!o_flag_used) {
+      if (!q_flag_used) {
+        fprintf(stderr, "Notify: File '%s' was generated.\n", filename_s.c_str());
+      }
 
+      fclose(file);
+    }
+  }
+  
+  if (o_flag_used) {
+    fprintf(file, "\n\n}\n");
+    if (!q_flag_used) {
+      fprintf(stderr, "Notify: File 'XSD_Definitions.ttcn' was generated.\n");
+    }
     fclose(file);
   }
 }
diff --git a/xsdconvert/converter.cc b/xsdconvert/converter.cc
index 69f8ae11981c69bf95b45512c6bb8a9d6dfb0cdf..07413b4b0a93d20742850deafc1bb9a115f6f98d 100644
--- a/xsdconvert/converter.cc
+++ b/xsdconvert/converter.cc
@@ -38,6 +38,7 @@ bool g_flag_used = true;
 bool h_flag_used = false;
 bool m_flag_used = false;
 bool n_flag_used = false; // Undocumented. Internal use only with makefilegen
+bool o_flag_used = false;
 bool p_flag_used = false;
 bool s_flag_used = false;
 bool t_flag_used = false;
@@ -74,7 +75,7 @@ int main(int argc, char **argv) {
   char c;
   opterr = 0;
 
-  while ((c = getopt(argc, argv, "cdef:ghJ:mnpqstvwxz")) != -1) {
+  while ((c = getopt(argc, argv, "cdef:ghJ:mnopqstvwxz")) != -1) {
     switch (c) {
       case 'c':
         c_flag_used = true;
@@ -102,6 +103,9 @@ int main(int argc, char **argv) {
       case 'n':
         n_flag_used = true;
         break;
+      case 'o':
+        o_flag_used = true;
+        break;
       case 'p':
         p_flag_used = true;
         break;
@@ -244,7 +248,7 @@ static void printProductinfo() {
 
 static void printUsage(const char * argv0) {
   fprintf(stderr, "\n"
-    "usage: %s [-ceghmpstVwx] [-f file] [-J file] schema.xsd ...\n"
+    "usage: %s [-ceghmopstVwx] [-f file] [-J file] schema.xsd ...\n"
     "	or %s -v\n"
     "\n"
     "OPTIONS:\n"
@@ -254,6 +258,7 @@ static void printUsage(const char * argv0) {
     "	-g:		generate TTCN-3 code disallowing element substitution\n"
     "	-h:		generate TTCN-3 code allowing type substitution\n"
     "	-m:		generate only the UsefulTtcn3Types and XSD predefined modules\n"
+    "	-o:		generate all definitions into one module (called XSD_Definitions)\n"
     "	-p:		do not generate the UsefulTtcn3Types and XSD predefined modules\n"
     "	-q:		quiet mode - disable the issue of status messages\n"
     "	-s:		parse and validate only - no TTCN-3 module generation\n"
diff --git a/xsdconvert/converter.hh b/xsdconvert/converter.hh
index 1dd360080bbb38b89a9e25b54419f0740927cc20..9efbbd1bbbee8051baa54dbe4fb9a4ca31c49126 100644
--- a/xsdconvert/converter.hh
+++ b/xsdconvert/converter.hh
@@ -21,6 +21,7 @@ extern bool g_flag_used;
 extern bool h_flag_used;
 extern bool m_flag_used;
 extern bool n_flag_used; // Undocumented. Internal use only with makefilegen
+extern bool o_flag_used;
 extern bool p_flag_used;
 extern bool s_flag_used;
 extern bool t_flag_used;