content: import 'package:flutter/material.dart';
  //code taken from https://www.didierboelens.com/2018/12/reactive-programming---streams---bloc---practical-use-cases/#1-bloc-provider-and-inheritedwidget
  
  Type _typeOf<T>() => T;
  
  abstract class BlocBase {
    void dispose();
  }
  
  class BlocProvider<T extends BlocBase> extends StatefulWidget {
    BlocProvider({
      Key key,
      @required this.child,
      @required this.bloc,
    }) : super(key: key);
  
    final Widget child;
    final T bloc;
  
    @override
    _BlocProviderState<T> createState() => _BlocProviderState<T>();
  
    static T of<T extends BlocBase>(BuildContext context) {
      final type = _typeOf<_BlocProviderInherited<T>>();
      _BlocProviderInherited<T> provider =
          context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
      return provider?.bloc;
    }
  }
  
  class _BlocProviderState<T extends BlocBase> extends State<BlocProvider<T>> {
    @override
    void dispose() {
      widget.bloc?.dispose();
      print("bloc provider disposing ${widget.bloc}");
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return new _BlocProviderInherited<T>(
        bloc: widget.bloc,
        child: widget.child,
      );
    }
  }
  
  class _BlocProviderInherited<T> extends InheritedWidget {
    _BlocProviderInherited({
      Key key,
      @required Widget child,
      @required this.bloc,
    }) : super(key: key, child: child);
  
    final T bloc;
  
    @override
    bool updateShouldNotify(_BlocProviderInherited oldWidget) => false;
  }
  