diff --git a/api-openbis-java/build.gradle b/api-openbis-java/build.gradle
index 967eea87100584b7f4335ed124f9912b24aa965d..18e5cd6c80135c67e71d4ebb58fc90b8a2324288 100644
--- a/api-openbis-java/build.gradle
+++ b/api-openbis-java/build.gradle
@@ -70,8 +70,10 @@ generateTypeScript {
             "ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.SampleIdDeserializer",
             "ch.ethz.sis.openbis.generic.asapi.v3.dto.common.property.PropertiesDeserializer"]
     mapClasses = "asInterfaces"
+    importDeclarations = ["export default openbis"]
     outputKind = 'module'
     outputFileType = 'declarationFile'
+    namespace = 'openbis'
     customTypeNaming = [
             "ch.ethz.sis.openbis.generic.OpenBIS:facade",
             "ch.ethz.sis.openbis.generic.asapi.v3.dto.pat.search.PersonalAccessTokenSessionNameSearchCriteria:PersonalAccessTokenSessionNameSearchCriteria",
diff --git a/api-openbis-javascript/bin/webpack.config.v3api.generate.entry.template.js b/api-openbis-javascript/bin/webpack.config.v3api.generate.entry.template.js
index be858610b197ee3a1bea24dd3420bf1e0ca8936d..0dc91c5c94905c7b2f569cba2f51bd20752591ba 100644
--- a/api-openbis-javascript/bin/webpack.config.v3api.generate.entry.template.js
+++ b/api-openbis-javascript/bin/webpack.config.v3api.generate.entry.template.js
@@ -24,7 +24,7 @@ dtos
 
 console.log("import stjs from '../../src/v3/lib/stjs/js/stjs'")
 console.log("import underscore from '../../src/v3/lib/underscore/js/underscore'")
-console.log("import openbis from '../../src/v3/openbis'")
+console.log("import facade from '../../src/v3/openbis'")
 
 // use bundled DTOs when parsing JSON responses (i.e. overwrite the default Json.requireFn - it would load DTOs from the server using RequireJS)
 
@@ -62,7 +62,7 @@ console.log('\nstjs._ = underscore')
 // This way any DTOs with duplicated simple names can still be accessed via their full names.
 
 var exported = {
-  "openbis" : "$$openbis$$",
+  "facade" : "$$facade$$",
   "noConflict" : "$$noConflict$$"
 }
 
diff --git a/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddMethodsExtension.java b/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddMethodsExtension.java
index 5942392d0151199496fdfe66754868a4da6c0460..549e424598598b873cf0cbb7aacf5fbcc1a489b9 100644
--- a/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddMethodsExtension.java
+++ b/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddMethodsExtension.java
@@ -37,6 +37,7 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Executable;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
 import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -150,6 +151,34 @@ public class AddMethodsExtension extends Extension
         return tsType;
     }
 
+    private static List<TsType.GenericVariableType> resolveTypeParameters(TsBeanModel bean, TsModel model, ProcessingContext processingContext, boolean withBounds){
+        TypeVariable<? extends Class<?>>[] typeParameters = bean.getOrigin().getTypeParameters();
+        return Arrays.stream(typeParameters).map(t ->
+        {
+            Type[] boundsTypes = t.getBounds();
+            if (withBounds && boundsTypes.length > 0)
+            {
+                try
+                {
+                    List<String> boundsStrings = new ArrayList<>();
+                    for (Type boundType : boundsTypes)
+                    {
+                        TsType tsBoundType = resolveGenericType(bean.getOrigin(), boundType, model, processingContext);
+                        boundsStrings.add(tsBoundType.toString());
+                    }
+
+                    return new TsType.GenericVariableType(t.getName() + " extends " + boundsStrings.get(0));
+                } catch (UnresolvedTypeException e)
+                {
+                    return new TsType.GenericVariableType(t.getName());
+                }
+            } else
+            {
+                return new TsType.GenericVariableType(t.getName());
+            }
+        }).collect(Collectors.toList());
+    }
+
     private static TsType getReturnType(TsBeanModel bean, Method method, TsModel model, ProcessingContext processingContext)
     {
         return resolveGenericType(bean.getOrigin(), method.getGenericReturnType(), model, processingContext);
@@ -229,13 +258,17 @@ public class AddMethodsExtension extends Extension
         List<TsParameterModel> paramsModel =
                 paramsWithoutDeclaringClass.stream().map(param -> new TsParameterModel(param.name, param.getTsType())).collect(Collectors.toList());
         TsType returnType = null;
-        if (beanModel.getTypeParameters() != null && !beanModel.getTypeParameters().isEmpty())
+
+        List<TsType.GenericVariableType> typeParameters = resolveTypeParameters(beanModel, model, processingContext, false);
+
+        if (!typeParameters.isEmpty())
         {
-            returnType = new TsType.GenericReferenceType(beanModel.getName(), beanModel.getTypeParameters());
+            returnType = new TsType.GenericReferenceType(beanModel.getName(), typeParameters);
         } else
         {
             returnType = new TsType.ReferenceType(beanModel.getName());
         }
+
         logger.info(String.format("Processing constructor %s, with params %s and return type %s", constructor, params, returnType));
         return new TsMethodModel("new ", TsModifierFlags.None, beanModel.getTypeParameters(), paramsModel, returnType, null, null);
     }
@@ -303,7 +336,16 @@ public class AddMethodsExtension extends Extension
             TypeProcessor localProcessor = new DefaultTypeProcessor();
             ProcessingContext processingContext = new ProcessingContext(context.getSymbolTable(), localProcessor);
             //Add table of mapped types
-            Stream<TsBeanModel> processedBeans = model.getBeans().stream().map(bean ->
+
+            List<TsBeanModel> processedBeans = model.getBeans().stream().map(bean ->
+            {
+                List<TsType.GenericVariableType> tsTypeParameters = resolveTypeParameters(bean, model, processingContext, true);
+                return new TsBeanModel(bean.getOrigin(), bean.getCategory(), bean.isClass(), bean.getName(), tsTypeParameters,
+                        bean.getParent(), bean.getExtendsList(), bean.getImplementsList(), bean.getProperties(), bean.getConstructor(),
+                        bean.getMethods(), bean.getComments());
+            }).collect(Collectors.toList());
+
+            processedBeans = processedBeans.stream().map(bean ->
             {
                 if (asnycClasses.contains(bean.getOrigin().getName()))
                 {
@@ -312,7 +354,7 @@ public class AddMethodsExtension extends Extension
                 {
                     return addFunctions(bean, model, processingContext, AddMethodsExtension::makeFunction);
                 }
-            });
+            }).collect(Collectors.toList());
 
             List<TsBeanModel> processedBeansWithSeparatedConstructors = new LinkedList<>();
 
@@ -331,16 +373,13 @@ public class AddMethodsExtension extends Extension
                                     Collections.emptyList(), null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), null,
                                     constructors, Collections.emptyList());
                     processedBeansWithSeparatedConstructors.add(constructorBean);
-
-                    TsBeanModel beanWithoutConstructors =
-                            new TsBeanModel(bean.getOrigin(), bean.getCategory(), bean.isClass(), bean.getName(), bean.getTypeParameters(),
-                                    bean.getParent(), bean.getExtendsList(), bean.getImplementsList(), bean.getProperties(), bean.getConstructor(),
-                                    regularMethods, bean.getComments());
-                    processedBeansWithSeparatedConstructors.add(beanWithoutConstructors);
-                } else
-                {
-                    processedBeansWithSeparatedConstructors.add(bean);
                 }
+
+                TsBeanModel beanWithoutConstructors =
+                        new TsBeanModel(bean.getOrigin(), bean.getCategory(), bean.isClass(), bean.getName(), bean.getTypeParameters(),
+                                bean.getParent(), bean.getExtendsList(), bean.getImplementsList(), bean.getProperties(), bean.getConstructor(),
+                                regularMethods, bean.getComments());
+                processedBeansWithSeparatedConstructors.add(beanWithoutConstructors);
             });
 
             return model.withBeans(processedBeansWithSeparatedConstructors);
diff --git a/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddOpenBISModuleExtension.java b/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddOpenBISModuleExtension.java
index ef97b43a908ab0d1fe378377bf0e1c4aed3fa90c..03dc2a44aab4b53780b592b6c422641acfae5692 100644
--- a/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddOpenBISModuleExtension.java
+++ b/lib-typescriptprocessor/source/java/ch/empa/tsprocessor/AddOpenBISModuleExtension.java
@@ -55,22 +55,14 @@ public class AddOpenBISModuleExtension extends Extension
                     {
                         properties.add(new TsPropertyModel(bean.getName().getSimpleName(),
                                 new TsType.ReferenceType(new Symbol(bean.getName().getSimpleName() + "Constructor")), null, true, null));
-                    } else
-                    {
-                        properties.add(
-                                new TsPropertyModel(bean.getName().getSimpleName(), new TsType.ReferenceType(bean.getName()), null, true, null));
                     }
                 }
             }
 
-            beans.add(new TsBeanModel(null, TsBeanCategory.Data, false, new Symbol("openbis"), null, null, null, null, properties, null, null, null));
+            beans.add(new TsBeanModel(null, TsBeanCategory.Data, false, new Symbol("bundle"), null, null, null, null, properties, null, null, null));
 
             return model.withBeans(beans);
         }));
     }
 
-    @Override public void emitElements(final Writer writer, final Settings settings, final boolean exportKeyword, final TsModel model)
-    {
-        writer.writeIndentedLine("export default openbis");
-    }
 }