internal async Task Initiate()
    {

      // desubscribe from all day monitors and clear them up
      foreach (var monitor in m_dayMonitors)
        subscribeToThresholdMonitor(monitor.Value, false);
      m_dayMonitors.Clear();

      subscribeToUserCache(false);

      var allSets = (ContractSet[])Enum.GetValues(typeof(ContractSet));

      // desubscribe from update to userthresholds and clear them
      Array.ForEach(m_editLines.ToArray(), x => subscribeToEditLine(x, false));
      m_editLines.Clear();


      foreach (var set in allSets)
      {
        // set up the lines by which the user will edit the thresholds
        var userConfig = await UserThresholdCache.Intance().GetOrCreateSpreadVolumeMonitorForSet(set);
        var line = new ThresholdEditLine(set, userConfig.Threshold);
        subscribeToEditLine(line);
        m_editLines.Add(line);

        var ds = DaySet.Get(set);

        // if the contract set is live, then set up a monitor on that day, rebuild matching lines and subscribe to updates from it
        if (ds.Status.IsLive())
        {
          var newMonitor = new ThresholdMonitor(ds.NextRollDay, userConfig);
          m_dayMonitors.Add(set, newMonitor);
          subscribeToThresholdMonitor(newMonitor);
          rebuildMatchingLines(newMonitor);
        }
      }

      // subscribe to update on the user's threshold items
      subscribeToUserCache();

      HasBeenInitiated = true;
    }
    private void subscribeToThresholdMonitor(ThresholdMonitor monitor_, bool do_ = true)
    {
      monitor_.ValueUpdated -= handleMonitorFired;

      if (!do_)
        return;

      monitor_.ValueUpdated += handleMonitorFired;
    }
    private void rebuildMatchingLines(ThresholdMonitor monitor_)
    {
      var begin = monitor_.Source.GetDayBeginEndMonitor().StartDate;

      try
      {
        OnNotificationsRebuilding(new NotificationsRebuildingEventArgs(monitor_.Source.Set, true));
        m_rebuilding = true;
        monitor_.ReplayFrom(begin);
      }
      finally
      {
        m_rebuilding = false;
        OnNotificationsRebuilding(new NotificationsRebuildingEventArgs(monitor_.Source.Set, false));
      }
    }
    /// <summary>
    /// handler for the user cache being updated - needs to rebuild the list based on the new update
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e_"></param>
    private void handleUserCacheChanged(object sender, MongoBackCacheChangedArgs<FlowThreshold> e_)
    {
      if (e_ == null || e_.Item == null) return;

      if (e_.Item.Field != DayField.SpreadVolume) return;

      #region  ensure edit line is in line - should always be
      {
        var editLine = m_editLines.FirstOrDefault(x => x.Set == e_.Item.Set);

        if (editLine == null) return;

        // this shouldn't happen
        if (editLine.Threshold != e_.Item.Threshold)
        {
          subscribeToEditLine(editLine, false);
          editLine.Threshold = e_.Item.Threshold;
          subscribeToEditLine(editLine);
        }
      }
      #endregion

      // clearup any existing monitor
      if (m_dayMonitors.ContainsKey(e_.Item.Set))
      {
        m_dayMonitors[e_.Item.Set].Dispose();
        subscribeToThresholdMonitor(m_dayMonitors[e_.Item.Set], false);
      }

      var ds = DaySet.Get(e_.Item.Set);

      if (!ds.Status.IsLive())
        return;

      var newMonitor = new ThresholdMonitor(ds.NextRollDay, e_.Item);
      m_dayMonitors[e_.Item.Set] = newMonitor;

      subscribeToThresholdMonitor(m_dayMonitors[e_.Item.Set]);

      rebuildMatchingLines(newMonitor);
    }