internal static IChannel CreateFromJson(ChannelJson json, [CanBeNull] object state) { IChannel res = null; if (_typeCaches.ContainsKey(json.type)) { _globalCache.Mutex(() => { ICache <IChannel> cache = _typeCaches[json.type]; cache.Mutex(() => { if (cache.Contains(json.id)) { res = cache[json.id]; } else if (_globalCache.Contains(json.id)) { throw new WrongChannelTypeException("JSON specifies type of channel is " + json.type + ", but cached data says it should be " + _globalCache[json.id].Type + "."); } else { switch (json.type) { case ChannelType.DirectMessage: case ChannelType.GroupDirectMessage: res = new DirectMessageTextChannel(json, json.id); TextChannel.Populate((TextChannel)res, json, state); break; case ChannelType.ServerCategory: res = new ChannelCategory(json.id, json.id); ChannelCategory.Populate((ChannelCategory)res, json, state); break; case ChannelType.ServerText: res = new ServerTextChannel(json, json.id); TextChannel.Populate((TextChannel)res, json, state); break; } _globalCache.Add(res); cache.Add(res); } }); }); } return(res); }