internal PerSocketDirectionStats(bool sendOrReceive, SocketDirection direction)
            {
                StatisticNameFormat batchSizeStatName      = sendOrReceive ? StatisticNames.MESSAGING_SENT_BATCH_SIZE_PER_SOCKET_DIRECTION : StatisticNames.MESSAGING_RECEIVED_BATCH_SIZE_PER_SOCKET_DIRECTION;
                StatisticNameFormat batchHistogramStatName = sendOrReceive ? StatisticNames.MESSAGING_SENT_BATCH_SIZE_BYTES_HISTOGRAM_PER_SOCKET_DIRECTION : StatisticNames.MESSAGING_RECEIVED_BATCH_SIZE_BYTES_HISTOGRAM_PER_SOCKET_DIRECTION;

                averageBatchSize        = AverageValueStatistic.FindOrCreate(new StatisticName(batchSizeStatName, Enum.GetName(typeof(SocketDirection), direction)));
                batchSizeBytesHistogram = ExponentialHistogramValueStatistic.Create_ExponentialHistogram(
                    new StatisticName(batchHistogramStatName, Enum.GetName(typeof(SocketDirection), direction)),
                    NUM_MSG_SIZE_HISTOGRAM_CATEGORIES);
            }
        internal static void Init(bool silo)
        {
            if (silo)
            {
                LocalMessagesSent    = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_SENT_LOCALMESSAGES);
                ConnectedClientCount = CounterStatistic.FindOrCreate(StatisticNames.GATEWAY_CONNECTED_CLIENTS, false);
            }

            MessagesSentTotal        = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_SENT_MESSAGES_TOTAL);
            MessagesSentPerDirection = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];
            foreach (var direction in Enum.GetValues(typeof(Message.Directions)))
            {
                MessagesSentPerDirection[(int)direction] = CounterStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.MESSAGING_SENT_MESSAGES_PER_DIRECTION, Enum.GetName(typeof(Message.Directions), direction)));
            }

            MessagesReceived             = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_RECEIVED_MESSAGES_TOTAL);
            MessagesReceivedPerDirection = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];
            foreach (var direction in Enum.GetValues(typeof(Message.Directions)))
            {
                MessagesReceivedPerDirection[(int)direction] = CounterStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.MESSAGING_RECEIVED_MESSAGES_PER_DIRECTION, Enum.GetName(typeof(Message.Directions), direction)));
            }

            TotalBytesSent      = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_SENT_BYTES_TOTAL);
            totalBytesReceived  = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_RECEIVED_BYTES_TOTAL);
            HeaderBytesSent     = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_SENT_BYTES_HEADER);
            headerBytesReceived = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_RECEIVED_BYTES_HEADER);
            FailedSentMessages  = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];
            DroppedSentMessages = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];
            RejectedMessages    = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];

            ReroutedMessages = new CounterStatistic[Enum.GetValues(typeof(Message.Directions)).Length];
            foreach (var direction in Enum.GetValues(typeof(Message.Directions)))
            {
                ReroutedMessages[(int)direction] = CounterStatistic.FindOrCreate(
                    new StatisticName(StatisticNames.MESSAGING_REROUTED_PER_DIRECTION, Enum.GetName(typeof(Message.Directions), direction)));
            }

            sentMsgSizeHistogram    = ExponentialHistogramValueStatistic.Create_ExponentialHistogram(StatisticNames.MESSAGING_SENT_MESSAGESIZEHISTOGRAM, NUM_MSG_SIZE_HISTOGRAM_CATEGORIES);
            receiveMsgSizeHistogram = ExponentialHistogramValueStatistic.Create_ExponentialHistogram(StatisticNames.MESSAGING_RECEIVED_MESSAGESIZEHISTOGRAM, NUM_MSG_SIZE_HISTOGRAM_CATEGORIES);

            expiredAtSendCounter     = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_EXPIRED_ATSENDER);
            expiredAtReceiveCounter  = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_EXPIRED_ATRECEIVER);
            expiredAtDispatchCounter = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_EXPIRED_ATDISPATCH);
            expiredAtInvokeCounter   = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_EXPIRED_ATINVOKE);
            expiredAtRespondCounter  = CounterStatistic.FindOrCreate(StatisticNames.MESSAGING_EXPIRED_ATRESPOND);

            perSocketDirectionStatsSend    = new PerSocketDirectionStats[Enum.GetValues(typeof(SocketDirection)).Length];
            perSocketDirectionStatsReceive = new PerSocketDirectionStats[Enum.GetValues(typeof(SocketDirection)).Length];
            if (silo)
            {
                perSocketDirectionStatsSend[(int)SocketDirection.SiloToSilo]         = new PerSocketDirectionStats(true, SocketDirection.SiloToSilo);
                perSocketDirectionStatsSend[(int)SocketDirection.GatewayToClient]    = new PerSocketDirectionStats(true, SocketDirection.GatewayToClient);
                perSocketDirectionStatsReceive[(int)SocketDirection.SiloToSilo]      = new PerSocketDirectionStats(false, SocketDirection.SiloToSilo);
                perSocketDirectionStatsReceive[(int)SocketDirection.GatewayToClient] = new PerSocketDirectionStats(false, SocketDirection.GatewayToClient);
            }
            else
            {
                perSocketDirectionStatsSend[(int)SocketDirection.ClientToGateway]    = new PerSocketDirectionStats(true, SocketDirection.ClientToGateway);
                perSocketDirectionStatsReceive[(int)SocketDirection.ClientToGateway] = new PerSocketDirectionStats(false, SocketDirection.ClientToGateway);
            }

            perSiloSendCounters              = new ConcurrentDictionary <string, CounterStatistic>();
            perSiloReceiveCounters           = new ConcurrentDictionary <string, CounterStatistic>();
            perSiloPingSendCounters          = new ConcurrentDictionary <string, CounterStatistic>();
            perSiloPingReceiveCounters       = new ConcurrentDictionary <string, CounterStatistic>();
            perSiloPingReplyReceivedCounters = new ConcurrentDictionary <string, CounterStatistic>();
            perSiloPingReplyMissedCounters   = new ConcurrentDictionary <string, CounterStatistic>();
        }