anchor.diff:        ItemBean(type ?? this.type, data ?? this.data);
   }
   
  +abstract class AdapterSource {
  +  int get itemCount;
  +
  +  String getType(int index);
  +
  +  Object getData(int index);
  +
  +  AdapterSource update(int index, Object data, bool isStateCopied);
  +}
  +
  +abstract class MutableSource extends AdapterSource {
  +  @mustCallSuper
  +  @override
  +  MutableSource update(int index, Object data, bool isStateCopied) {
  +    final MutableSource result = isStateCopied ? this : clone();
  +    return result..setData(index, data);
  +  }
  +
  +  void setData(int index, Object data);
  +
  +  MutableSource clone();
  +}
  +
  +abstract class ImmutableSource extends AdapterSource {
  +  @mustCallSuper
  +  @override
  +  ImmutableSource update(int index, Object data, bool isStateCopied) =>
  +      setData(index, data);
  +
  +  ImmutableSource setData(int index, Object data);
  +
  +  ImmutableSource clone();
  +}
  +
  +class _Conn<T> implements AbstractConnector<T, AdapterSource> {
  +  final AbstractConnector<T, List<ItemBean>> connector;
  +
  +  _Conn(this.connector);
  +
  +  @override
  +  AdapterSource get(T state) => _ListSource(connector.get(state));
  +
  +  @override
  +  SubReducer<T> subReducer(Reducer<AdapterSource> reducer) {
  +    return connector.subReducer((List<ItemBean> list, Action action) {
  +      /// maybe a long loop
  +      final _ListSource listSource = reducer(_ListSource(list), action);
  +      return listSource.list;
  +    });
  +  }
  +}
  +
  +class _ListSource extends MutableSource {
  +  /// ignore:deprecated_member_use_from_same_package
  +  final List<ItemBean> list;
  +
  +  _ListSource(this.list);
  +
  +  @override
  +  MutableSource clone() => _ListSource(list.toList());
  +
  +  @override
  +  Object getData(int index) => list[index].data;
  +
  +  @override
  +  String getType(int index) => list[index].type;
  +
  +  @override
  +  int get itemCount => list.length;
  +
  +  @override
  +  void setData(int index, Object data) =>
  +      list[index] = ItemBean(list[index].type, data);
  +}
  +
   /// template is a map, driven by array
   class DynamicFlowAdapter<T> extends Logic<T> with RecycleContextMixin<T> {
     final Map<String, AbstractLogic<Object>> pool;
  -  final AbstractConnector<T, List<ItemBean>> connector;
  +
  +  final AbstractConnector<T, AdapterSource> sourceConn;
   
     DynamicFlowAdapter({
       @required this.pool,
  -    @required this.connector,
  +
  +    /// ignore:deprecated_member_use_from_same_package
  +    @deprecated AbstractConnector<T, List<ItemBean>> connector,
  +    @required AbstractConnector<T, AdapterSource> sourceConn2,
       ReducerFilter<T> filter,
       Reducer<T> reducer,
       Effect<T> effect,
  
positive.code: Reducer<T> _dynamicReducer<T>(
    Reducer<T> reducer,
    Map<String, AbstractLogic<Object>> pool,
    AbstractConnector<T, List<ItemBean>> connector,
  ) {
    final Reducer<List<ItemBean>> dyReducer =
        (List<ItemBean> state, Action action) {
      List<ItemBean> copy;
      for (int i = 0; i < state.length; i++) {
        final ItemBean itemBean = state[i];
        final AbstractLogic<Object> result = pool[itemBean.type];
        if (result != null) {
          final Object newData = result.onReducer(itemBean.data, action);
          if (newData != itemBean.data) {
            copy ??= state.toList();
            copy[i] = itemBean.clone(data: newData);
          }
        }
      }
  
negative.code: /// [_isSimilar] return false we should use cache state before reducer invoke.
  /// for reducer change state immediately but sub component will refresh on next
  /// frame. in this time the sub component will use cache state.
  Get<Object> _subGetter(Get<AdapterSource> getter, int index) {
    final AdapterSource curState = getter();
    String type = curState.getType(index);
    Object data = curState.getData(index);
  
    return () {
      final AdapterSource newState = getter();
  
      /// Either all sub-components use cache or not.
      if (newState != null && newState.itemCount > index) {
        final String newType = newState.getType(index);
        final Object newData = newState.getData(index);
  
        if (_couldReuse(
          typeA: type,
          typeB: newType,
          dataA: data,
          dataB: newData,
        )) {
          type = newType;
          data = newData;
        }
      }
  
      return data;
    };
  }
  
  bool _couldReuse({String typeA, String typeB, Object dataA, Object dataB}) {
    return typeA != typeB
        ? false
        : dataA.runtimeType != dataB.runtimeType
            ? false
            : (dataA is StateKey ? dataA.key() : null) ==
                (dataB is StateKey ? dataB.key() : null);
  }
  