class DeferredResultHolder {
	
	public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS";
	
	public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO";
	
	public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL";
	
	public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG";

	public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD";
	
	public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG";
	
	public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO";

	public static final String CALLBACK_CMD_PLAY = "CALLBACK_PLAY";

	public static final String CALLBACK_CMD_PLAYBACK = "CALLBACK_PLAYBACK";

	public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD";

	public static final String CALLBACK_CMD_PROXY = "CALLBACK_PROXY";

	public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";

	public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL";

	public static final String CALLBACK_CMD_MOBILE_POSITION = "CALLBACK_CMD_MOBILE_POSITION";

	public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";

	public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";

	public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";

	public static final String CALLBACK_CMD_SNAP= "CALLBACK_SNAP";

	private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>();


	public void put(String key, String id, DeferredResultEx result) {
		Map<String, DeferredResultEx> deferredResultMap = map.get(key);
		if (deferredResultMap == null) {
			deferredResultMap = new ConcurrentHashMap<>();
			map.put(key, deferredResultMap);
		}
		deferredResultMap.put(id, result);
	}

	public void put(String key, String id, DeferredResult result) {<FILL_FUNCTION_BODY>}
	
	public DeferredResultEx get(String key, String id) {
		Map<String, DeferredResultEx> deferredResultMap = map.get(key);
		if (deferredResultMap == null || ObjectUtils.isEmpty(id)) {
			return null;
		}
		return deferredResultMap.get(id);
	}

	public Collection<DeferredResultEx> getAllByKey(String key) {
		Map<String, DeferredResultEx> deferredResultMap = map.get(key);
		if (deferredResultMap == null) {
			return null;
		}
		return deferredResultMap.values();
	}

	public boolean exist(String key, String id){
		if (key == null) {
			return false;
		}
		Map<String, DeferredResultEx> deferredResultMap = map.get(key);
		if (id == null) {
			return deferredResultMap != null;
		}else {
			return deferredResultMap != null && deferredResultMap.get(id) != null;
		}
	}

	/**
	 * 释放单个请求
	 * @param msg
	 */
	public void invokeResult(RequestMessage msg) {
		Map<String, DeferredResultEx> deferredResultMap = map.get(msg.getKey());
		if (deferredResultMap == null) {
			return;
		}
		DeferredResultEx result = deferredResultMap.get(msg.getId());
		if (result == null) {
			return;
		}
		result.getDeferredResult().setResult(msg.getData());
		deferredResultMap.remove(msg.getId());
		if (deferredResultMap.size() == 0) {
			map.remove(msg.getKey());
		}
	}

	/**
	 * 释放所有的请求
	 * @param msg
	 */
	public void invokeAllResult(RequestMessage msg) {
		Map<String, DeferredResultEx> deferredResultMap = map.get(msg.getKey());
		if (deferredResultMap == null) {
			return;
		}
		synchronized (this) {
			deferredResultMap = map.get(msg.getKey());
			if (deferredResultMap == null) {
				return;
			}
			Set<String> ids = deferredResultMap.keySet();
			for (String id : ids) {
				DeferredResultEx result = deferredResultMap.get(id);
				if (result == null) {
					return;
				}
				if (result.getFilter() != null) {
					Object handler = result.getFilter().handler(msg.getData());
					result.getDeferredResult().setResult(handler);
				}else {
					result.getDeferredResult().setResult(msg.getData());
				}

			}
			map.remove(msg.getKey());
		}
	}


}

		Map<String, DeferredResultEx> deferredResultMap = map.get(key);
		if (deferredResultMap == null) {
			deferredResultMap = new ConcurrentHashMap<>();
			map.put(key, deferredResultMap);
		}
		deferredResultMap.put(id, new DeferredResultEx(result));
	
<no_super_class>