diff --git a/packages/provider/assets/index.html.ejs b/packages/provider/assets/index.html.ejs
index 3d35a5f69accc3305eae3ac28c870d9bf881eb7f..632576144de80430c2485daad1c5c71449f32f8a 100644
--- a/packages/provider/assets/index.html.ejs
+++ b/packages/provider/assets/index.html.ejs
@@ -1,7 +1,8 @@
 <!doctype html>
-<html>
+<html lang="de">
 <head>
     <meta charset="UTF-8">
+    <title>Provider Demo 1</title>
     <script type="module" src="dbp-provider.js"></script>
     <script type="module" src="dbp-provider-demo.js"></script>
     <!--
@@ -19,9 +20,16 @@
 </head>
 
 <body>
+    <pre>&lt;dbp-provider  id="root"  root="1" availability="global" >&lt;/dbp-provider&gt;</pre>
     <dbp-provider id="root" root="1" availability="global" lang="de">
         <dbp-provider-demo id="provider-demo" subscribe="lang:lang"></dbp-provider-demo>
     </dbp-provider>
+    <hr>
+    <ul>
+        <li>multiple, explicit providers</li>
+        <li><a href="/index2.html">automatic generated provider</a></li>
+        <li><a href="/index3.html">explicit provider</a></li>
+    </ul>
     <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p>
 </body>
 </html>
diff --git a/packages/provider/assets/index2.html.ejs b/packages/provider/assets/index2.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..1f85931d5d12b851a156550549c2540b5ead4a80
--- /dev/null
+++ b/packages/provider/assets/index2.html.ejs
@@ -0,0 +1,23 @@
+<!doctype html>
+<html lang="de">
+<head>
+    <meta charset="UTF-8">
+    <title>Provider Demo 2a</title>
+    <script type="module" src="dbp-provider.js"></script>
+    <script type="module" src="dbp-provider-demo2.js"></script>
+    <style>
+        body { padding: 50px;}
+    </style>
+</head>
+
+<body>
+    <dbp-provider-demo2 id="provider-demo" subscribe="lang:lang"></dbp-provider-demo2>
+    <hr>
+    <ul>
+        <li><a href="/index.html">multiple, explicit providers</a></li>
+        <li>automatic generated provider</li>
+        <li><a href="/index3.html">explicit provider</a></li>
+    </ul>
+    <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p>
+</body>
+</html>
diff --git a/packages/provider/assets/index3.html.ejs b/packages/provider/assets/index3.html.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..eeae9af581c64ac2efbff6b44365ea3d30d255ca
--- /dev/null
+++ b/packages/provider/assets/index3.html.ejs
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="de">
+<head>
+    <meta charset="UTF-8">
+    <title>Provider Demo 2b</title>
+    <script type="module" src="dbp-provider.js"></script>
+    <script type="module" src="dbp-provider-demo2.js"></script>
+    <style>
+        body { padding: 50px;}
+    </style>
+</head>
+
+<body>
+<pre>&lt;dbp-provider  id="child-of-body" root="1" lang="de" >&lt;/dbp-provider&gt;</pre>
+    <dbp-provider id="child-of-body" root="1" lang="de">
+        <dbp-provider-demo2 id="provider-demo" subscribe="lang:lang"></dbp-provider-demo2>
+    </dbp-provider>
+    <hr>
+    <ul>
+        <li><a href="/index.html">multiple, explicit providers</a></li>
+        <li><a href="/index2.html">automatic generated provider</a></li>
+        <li>explicit provider</li>
+    </ul>
+    <p>version: <span style="color: white; background-color: black;"><%= buildInfo.info %></span></p>
+</body>
+</html>
diff --git a/packages/provider/rollup.config.js b/packages/provider/rollup.config.js
index 75560d89d352a8bca7770c648b1fd2cc1815cc85..9e5b29024f15cf86bb7bc58ad65b382c2c0583a2 100644
--- a/packages/provider/rollup.config.js
+++ b/packages/provider/rollup.config.js
@@ -41,7 +41,7 @@ function getBuildInfo() {
 
 export default (async () => {
     return {
-        input: (build != 'test') ? ['src/dbp-provider.js', 'src/dbp-provider-demo.js'] : glob.sync('test/**/*.js'),
+        input: (build !== 'test') ? ['src/dbp-provider.js', 'src/dbp-provider-demo.js', 'src/dbp-provider-demo2.js'] : glob.sync('test/**/*.js'),
         output: {
             dir: 'dist',
             entryFileNames: '[name].js',
@@ -94,6 +94,8 @@ export default (async () => {
             copy({
                 targets: [
                     {src: 'assets/index.html', dest: 'dist'},
+                    {src: 'assets/index2.html', dest: 'dist'},
+                    {src: 'assets/index3.html', dest: 'dist'},
                     {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')},
                     {src: 'assets/favicon.ico', dest:'dist'},
                 ],
diff --git a/packages/provider/src/adapter-lit-element.js b/packages/provider/src/adapter-lit-element.js
index bcdf0929d479be253bd3c937117df3869dcc1fe6..cee656aa87b177797ec47d4bb2b84fab5f1f42b8 100644
--- a/packages/provider/src/adapter-lit-element.js
+++ b/packages/provider/src/adapter-lit-element.js
@@ -1,8 +1,50 @@
 import {LitElement} from "lit-element";
+import {Provider} from '@dbp-toolkit/provider';
 
 export class AdapterLitElement extends LitElement {
+    static inititialized=false;
+    static pingEventListener = false;
+
+    ping() {
+        if (AdapterLitElement.inititialized) {
+            return;
+        }
+        console.log('ping');
+        AdapterLitElement.pingEventListener = window.addEventListener('ping', e => AdapterLitElement.addRootProvider(e), false);
+        const event = new CustomEvent('ping',
+            {
+                bubbles: true,
+                composed: true,
+                detail: {
+                    callback: () => {
+                        console.log('ping by some Provider cancelled.');
+                        window.removeEventListener('ping', AdapterLitElement.pingEventListener, false);
+                    }
+                }
+            });
+        this.dispatchEvent(event);
+
+        AdapterLitElement.inititialized = true;
+    }
+
+    static addRootProvider(/*e*/) {
+        console.log('pong');
+        //console.dir(e);
+        window.removeEventListener('ping', this.pingEventListener, false);
+        this.pingEventListener = false;
+
+        window.dbpProvider = new Provider();
+        window.dbpProvider.root = true;
+        window.dbpProvider.id = 'magic-root-provider';
+        window.addEventListener('subscribe', window.dbpProvider.subscribing.bind(window.dbpProvider), false);
+        window.addEventListener('unsubscribe', window.dbpProvider.unsubscribing.bind(window.dbpProvider), false);
+        window.addEventListener('set-property', window.dbpProvider.settingProperty.bind(window.dbpProvider), false);
+
+    }
+
     constructor() {
         super();
+        this.ping();
         this.connected = false;
         this.deferSubscribe = false;
         this.deferUnSubscribe = false;
diff --git a/packages/provider/src/dbp-provider-demo.js b/packages/provider/src/dbp-provider-demo.js
index 10a482fb5cdd9e3a17597528f42c178824cf6e85..d2277a784323c7cfea7afebc87e65002d3cd4401 100644
--- a/packages/provider/src/dbp-provider-demo.js
+++ b/packages/provider/src/dbp-provider-demo.js
@@ -71,10 +71,8 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) {
     render() {
         return html`
             <section class="section">
-                <p>${i18n.t('demo.provider_description', {id: "root", description: "is the top most in hierarchy"})}</p>
-                <pre>&lt;dbp-provider  id="root"  root="1" availability="global" >&lt;/dbp-provider&gt;</pre>
                 <div class="container">
-                    <h1 class="title">${i18n.t('demo.provider')}-Demo</h1>
+                    <h1 class="title">${i18n.t('demo.provider')}-Demo 1</h1>
                 </div>
                 <div class="container">
                     <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
@@ -127,7 +125,6 @@ class DemoConsumer extends DBPLitElement {
         // default values
         this.foo = 100;
         this.bar = 900;
-        this.ping = 0;
         this.borderColor = 'green';
 
         this.status = 'local';
@@ -150,7 +147,6 @@ class DemoConsumer extends DBPLitElement {
             bar: { type: String },
             gong: { type: String },
             borderColor: { type: String, attribute: 'border-color' },
-            ping: { type: String }
         };
     }
 
diff --git a/packages/provider/src/dbp-provider-demo2.js b/packages/provider/src/dbp-provider-demo2.js
new file mode 100644
index 0000000000000000000000000000000000000000..8369171b2ce50cf9b68c08f41dcc81e4ed207efc
--- /dev/null
+++ b/packages/provider/src/dbp-provider-demo2.js
@@ -0,0 +1,188 @@
+import {i18n} from './i18n.js';
+import {css, html} from 'lit-element';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth';
+import * as commonUtils from '@dbp-toolkit/common/utils';
+import * as commonStyles from '@dbp-toolkit/common/styles';
+import {Provider} from '@dbp-toolkit/provider';
+import {LanguageSelect} from '@dbp-toolkit/language-select';
+import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element";
+
+
+class ProviderDemo2 extends ScopedElementsMixin(DBPLitElement) {
+
+    constructor() {
+        super();
+        this.lang = 'de';
+    }
+
+    static get scopedElements() {
+        return {
+            'dbp-auth-keycloak': AuthKeycloak,
+            'dbp-login-button': LoginButton,
+            'dbp-language-select': LanguageSelect,
+            'dbp-provider': Provider,
+            'dbp-consumer2': DemoConsumer2,
+        };
+    }
+
+    static get properties() {
+        return {
+            ...super.properties,
+            lang: { type: String },
+        };
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        i18n.changeLanguage(this.lang);
+
+    }
+
+    attributeChangedCallback(name, oldValue, newValue) {
+        console.log('ProviderDemo (' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')');
+        switch(name) {
+            case 'lang':
+                this.lang = newValue;
+                i18n.changeLanguage(this.lang);
+                break;
+            default:
+                super.attributeChangedCallback(name, oldValue, newValue);
+        }
+        this.render();
+    }
+
+    static get styles() {
+        // language=css
+        return [
+            commonStyles.getThemeCSS(),
+            commonStyles.getGeneralCSS(),
+            css`
+            h1.title {margin-bottom: 1em;}
+            div.container {margin-bottom: 1.5em; padding-left:20px;}
+            `
+        ];
+    }
+
+    get id() {
+        return this.getAttribute('id');
+    }
+
+    render() {
+        return html`
+            <section class="section">
+                <div class="container">
+                    <h1 class="title">${i18n.t('demo.provider')}-Demo 2</h1>
+                </div>
+                <div class="container">
+                    <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+                    <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
+                    <dbp-language-select></dbp-language-select>
+                </div>
+                <div class="container">
+                    <h2>${i18n.t('demo.consumer')}</h2>
+                    <p>${i18n.t('demo.consumer_description', {id: "c1", subscriptions: "border-color, lang"})}</p>
+                    <pre>&lt;dbp-consumer2  id="c1"  subscribe="border-color:bc,lang:lang" &gt;&lt;/dbp-consumer&gt;</pre>
+                    <dbp-consumer2 id="c1" subscribe="border-color:bc,lang:lang"></dbp-consumer2>
+                </div>
+            </section>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('dbp-provider-demo2', ProviderDemo2);
+
+// =======================================================
+
+class DemoConsumer2 extends DBPLitElement {
+    constructor() {
+        super();
+
+        this.lang = 'de';
+        // default values
+        this.foo = 100;
+        this.bar = 900;
+        this.borderColor = 'green';
+
+        this.status = 'local';
+
+        console.log('DemoConsumer2 constructor()');
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        i18n.changeLanguage(this.lang);
+        console.log('DemoConsumer2(' + this.id + ') connectedCallback()');
+        this.render();
+    }
+
+    static get properties() {
+        return {
+            ...super.properties,
+            lang: { type: String },
+            foo: { type: String },
+            bar: { type: String },
+            gong: { type: String },
+            borderColor: { type: String, attribute: 'border-color' },
+        };
+    }
+
+    attributeChangedCallback(name, oldValue, newValue) {
+        if (oldValue === newValue) {
+            return;
+        }
+
+        console.log('DemoConsumer2(' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')');
+        switch(name) {
+            case 'lang':
+                this.lang = newValue;
+                i18n.changeLanguage(this.lang);
+                break;
+            case 'foo':
+                this.foo = parseInt(newValue);
+                break;
+            case 'bar':
+                this.bar = parseInt(newValue);
+                break;
+            case 'status':
+                this.status = newValue;
+                break;
+            case 'border-color':
+                this['border-color'] = newValue;
+                break;
+            default:
+                super.attributeChangedCallback(name, oldValue, newValue);
+        }
+        this.render();
+    }
+
+    get id() {
+        return this.getAttribute('id');
+    }
+
+    render() {
+        if (! this.connected) {
+            return `not connected!`;
+        }
+        console.log('DemoConsumer2(' + this.id + ') render()');
+
+        const sum = this.foo + this.bar;
+        return html`
+        <div style="border: ${this['border-color']} dotted; padding: 10px;">
+            <table style="width:200px;">
+                <tr style="background-color: #aaa;">
+                    <th style="text-align: left;">${i18n.t('consumer.item')}</th>
+                    <th style="text-align: right;">${i18n.t('consumer.price')}</th>
+                </tr>
+                <tr><td>foo</td><td style="text-align: right;">${this.foo}</td></tr>
+                <tr><td>bar</td><td style="text-align: right;">${this.bar}</td></tr>
+                <tr><td>${i18n.t('consumer.sum')}</td><td style="text-align: right;">${sum}</td></tr>
+            </table>
+            <p>Status: <b>${this.status}</b></p>
+        </div>
+        `;
+    }
+
+}
+
+customElements.define('dbp-consumer2', DemoConsumer2);
diff --git a/packages/provider/src/provider.js b/packages/provider/src/provider.js
index fc3aff38c9ac5b246e7b773cf6bb4e8dbb5576fa..37543679f3d59ed7292c0fe77079330d9b0121b4 100644
--- a/packages/provider/src/provider.js
+++ b/packages/provider/src/provider.js
@@ -37,51 +37,12 @@ export class Provider extends HTMLElement {
 
         const that = this;
 
-        this.addEventListener('subscribe', function (e) {
-            const name = e.detail.name;
-            if (that.hasProperty(name) || that.root) {
-                console.log('Provider(' + that.id + ') eventListener("subscribe",..) name "' + name + '" found.');
-                that.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender});
-
-                e.detail.callback(that.getProperty(name));
-                e.stopPropagation();
-            }
-        }, false);
-
-        this.addEventListener('unsubscribe', function (e) {
-            const name = e.detail.name;
-            const sender = e.detail.sender;
-            if (that.hasProperty(name) || that.root) {
-                console.log('Provider(' + that.id + ') eventListener("unsubscribe",..) name "' + name + '" found.');
-                that.callbackStore.forEach(item => {
-                    if (item.sender === sender && item.name === name) {
-                        const index = that.callbackStore.indexOf(item);
-                        that.callbackStore.splice(index, 1);
-                        console.log('Provider(' + that.id + ') eventListener for name "' + name + '" removed.');
-                    }
-                });
-
-                e.stopPropagation();
-            }
-        }, false);
-
-        // listen to property changes
-        this.addEventListener('set-property', function (e) {
-            const name = e.detail.name;
-            const value = e.detail.value;
-
-            if (that.hasProperty(name) || that.root) {
-                console.log('Provider(' + that.id + ') eventListener("set-property",..) name "' + name + '" found.');
-                that.setProperty(name, value);
-
-                that.callbackStore.forEach(item => {
-                    if (item.name === name) {
-                        item.callback(value);
-                    }
-                });
-
-                e.stopPropagation();
-            }
+        this.addEventListener('subscribe', this.subscribing.bind(this), false);
+        this.addEventListener('unsubscribe', this.unsubscribing.bind(this), false);
+        this.addEventListener('set-property', this.settingProperty.bind(this), false);
+        this.addEventListener('ping', function (e) {
+            e.stopPropagation();
+            e.detail.callback();
         }, false);
 
         // Options for the observer (which mutations to observe)
@@ -132,4 +93,54 @@ export class Provider extends HTMLElement {
     get id() {
         return this.getAttribute('id');
     }
+
+    set id(id) {
+        this.setAttribute('id', id);
+    }
+
+    subscribing (e) {
+        const name = e.detail.name;
+        if (this.hasProperty(name) || this.root) {
+            console.log('Provider(' + this.id + ') eventListener("subscribe",..) name "' + name + '" found.');
+            this.callbackStore.push({name: name, callback: e.detail.callback, sender: e.detail.sender});
+
+            e.detail.callback(this.getProperty(name));
+            e.stopPropagation();
+        }
+    }
+
+    unsubscribing (e) {
+        const name = e.detail.name;
+        const sender = e.detail.sender;
+        if (this.hasProperty(name) || this.root) {
+            console.log('Provider(' + this.id + ') eventListener("unsubscribe",..) name "' + name + '" found.');
+            this.callbackStore.forEach(item => {
+                if (item.sender === sender && item.name === name) {
+                    const index = this.callbackStore.indexOf(item);
+                    this.callbackStore.splice(index, 1);
+                    console.log('Provider(' + this.id + ') eventListener for name "' + name + '" removed.');
+                }
+            });
+
+            e.stopPropagation();
+        }
+    }
+
+    settingProperty (e) {
+        const name = e.detail.name;
+        const value = e.detail.value;
+
+        if (this.hasProperty(name) || this.root) {
+            console.log('Provider(' + this.id + ') eventListener("set-property",..) name "' + name + '" found.');
+            this.setProperty(name, value);
+
+            this.callbackStore.forEach(item => {
+                if (item.name === name) {
+                    item.callback(value);
+                }
+            });
+
+            e.stopPropagation();
+        }
+    }
 }