public synchronized void updateCategoryTrend(long catId) {
    String trendStr = "trend_unknown";
    float stdDev = 0.0f;
    float lastTrend = 0.0f;
    float newTrend = 0.0f;

    gatherLatestDatapointsLocking(catId, mHistory);
    TimeSeries ts = getSeriesByIdLocking(catId);
    if (ts == null) return;

    if (ts.getDbRow().getSynthetic() == true) return;

    lastTrend = ts.getTrendStats().mTrendPrev;
    newTrend = ts.getTrendStats().mTrend;
    stdDev = ts.getValueStats().mStdDev;

    TrendState state =
        Number.getTrendState(lastTrend, newTrend, ts.getDbRow().getGoal(), mSensitivity, stdDev);
    trendStr = Number.mapTrendStateToString(state);

    mDbh.updateCategoryTrend(catId, trendStr, newTrend);

    if (ts.getDependees() != null && ts.getDependees().size() > 0) {
      for (int i = 0; i < ts.getDependees().size(); i++) {
        TimeSeries dependee = ts.getDependees().get(i);

        for (int j = 0; j < dependee.getDependents().size(); j++) {
          TimeSeries tmp = dependee.getDependents().get(j);
          if (tmp != null) gatherLatestDatapointsLocking(tmp.getDbRow().getId(), mHistory);
        }

        Formula formula = mFormulaCache.getFormula(dependee.getDbRow().getId());
        ArrayList<Datapoint> calculated = formula.apply(dependee.getDependents());
        dependee.setDatapoints(null, calculated, null, true);

        lastTrend = dependee.getTrendStats().mTrendPrev;
        newTrend = dependee.getTrendStats().mTrend;
        stdDev = dependee.getValueStats().mStdDev;

        state =
            Number.getTrendState(
                lastTrend, newTrend, dependee.getDbRow().getGoal(), mSensitivity, stdDev);
        trendStr = Number.mapTrendStateToString(state);

        mDbh.updateCategoryTrend(dependee.getDbRow().getId(), trendStr, newTrend);
      }
    }
  }