// utils
        // todo: remove
        public static int getPeriod(canMessage m1, canMessage m2)
        {
            int ts1 = m1.getTimestamp();
            int ts2 = m2.getTimestamp();

            return(getPeriod(ts1, ts2));
        }
        public void remove(canMessage msg)
        {
            canMessage prev = find(msg);

            if (!prev.isEmpty())
            {
                m_list.Remove(prev);
            }
        }
        private canMessage find(canMessage msg)
        {
            int idx = findIndex(msg);

            if (idx >= 0)
            {
                return(m_list[idx]);
            }
            return(null);
        }
        public override bool Equals(Object obj)
        {
            // Check for null values and compare run-time types.
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            canMessage p = (canMessage)obj;

            return(getCanId() == p.getCanId() &&    // id
                   is29bitId() == p.is29bitId() &&  // id len
                   getDlc() == p.getDlc() &&        // dlc
                   getData() == p.getData());       // data
        }
        public void add(canMessage msg)
        {
            int idx = findIndex(msg);

            if (idx >= 0)
            {
                canMessage prev = m_list[idx];
                int        per  = canMessage.getPeriod(msg.getTimestamp(), prev.getTimestamp());
                msg.period  = per;
                m_list[idx] = msg;
            }
            else
            {
                m_list.Add(msg);
            }

            return;
        }
 private int findIndex(canMessage msg)
 {
     return(m_list.FindIndex(x => x.Id == msg.Id && x.getDlc() == msg.getDlc()));
 }
        public canMessage get(canMessage msg)
        {
            canMessage res = find(msg);

            return(res);
        }
        //-------------------------------------------------------------------------------------------------

        // is a row selected
        private bool isSelected(canMessage msg)
        {
            var row = getMsgRow(msg.getCanIdString(), msg.getDlc());

            return(row != null ? row.Selected : false);
        }