/**
         * Locate detection point configuration from server-side config file.
         *
         * @param search detection point that has been added to the system
         * @return DetectionPoint populated with configuration information from server-side config
         */
        public DetectionPoint findDetectionPoint(DetectionPoint search)
        {
            DetectionPoint detectionPoint = null;

            //detectionPoint = detectionPointCache.get(search.getId());
            detectionPoint = detectionPointCache[search.getId()];

            if (detectionPoint == null)
            {
                foreach (DetectionPoint configuredDetectionPoint in getDetectionPoints())
                {
                    if (configuredDetectionPoint.getId().Equals(search.getId()))
                    {
                        detectionPoint = configuredDetectionPoint;

                        //cache
                        detectionPointCache.Add(detectionPoint.getId(), detectionPoint);

                        break;
                    }
                }
            }

            return(detectionPoint);
        }
        /**
         * Lookup configured {@link Response} objects for specified {@link DetectionPoint}
         *
         * @param triggeringDetectionPoint {@link DetectionPoint} that triggered {@link Attack}
         * @return collection of {@link Response} objects for given {@link DetectionPoint}
         */
        protected Collection <Response> findPossibleResponses(DetectionPoint triggeringDetectionPoint)
        {
            //Collection<Response> possibleResponses = new List<Response>();
            Collection <Response> possibleResponses = new Collection <Response>();

            foreach (DetectionPoint configuredDetectionPoint in appSensorServer.getConfiguration().getDetectionPoints())
            {
                if (configuredDetectionPoint.getId().Equals(triggeringDetectionPoint.getId()))
                {
                    possibleResponses = configuredDetectionPoint.getResponses();
                    break;
                }
            }
            return(possibleResponses);
        }
        /**
         * {@inheritDoc}
         */
        public override Collection <Attack> findAttacks(SearchCriteria criteria)
        {
            if (criteria == null)
            {
                //throw new IllegalArgumentException("criteria must be non-null");
                throw new ArgumentException("criteria must be non-null");
            }

            //Collection<Attack> matches = new List<Attack>();
            Collection <Attack> matches = new Collection <Attack>();

            User           user           = criteria.GetUser();
            DetectionPoint detectionPoint = criteria.GetDetectionPoint();
            //Collection<string> detectionSystemIds = criteria.getDetectionSystemIds();
            HashSet <string> detectionSystemIds = criteria.getDetectionSystemIds();
            DateTime?        earliest           = DateUtils.fromString(criteria.getEarliest());

            Collection <Attack> attacks = loadAttacks();

            foreach (Attack attack in attacks)
            {
                //check user match if user specified
                bool userMatch = (user != null) ? user.Equals(attack.GetUser()) : true;

                //check detection system match if detection systems specified
                //bool detectionSystemMatch = (detectionSystemIds != null && detectionSystemIds.size() > 0) ?
                bool detectionSystemMatch = (detectionSystemIds != null && detectionSystemIds.Count > 0) ?
                                            detectionSystemIds.Contains(attack.GetDetectionSystemId()) : true;

                //check detection point match if detection point specified
                bool detectionPointMatch = (detectionPoint != null) ?
                                           detectionPoint.getId().Equals(attack.GetDetectionPoint().getId()) : true;

                //bool earliestMatch = (earliest != null) ? earliest.isBefore(DateUtils.fromString(attack.GetTimestamp())) : true;
                bool earliestMatch = (earliest != null) ? earliest < DateUtils.fromString(attack.GetTimestamp()) : true;

                if (userMatch && detectionSystemMatch && detectionPointMatch && earliestMatch)
                {
                    matches.Add(attack);
                }
            }

            return(matches);
        }
        /**
         * {@inheritDoc}
         */
        public override Collection <Event> findEvents(SearchCriteria criteria)
        {
            if (criteria == null)
            {
                throw new ArgumentException("criteria must be non-null");
            }

            Collection <Event> matches = new Collection <Event>();

            User           user           = criteria.GetUser();
            DetectionPoint detectionPoint = criteria.GetDetectionPoint();
            //Collection<string> detectionSystemIds = criteria.getDetectionSystemIds();
            HashSet <string> detectionSystemIds = criteria.getDetectionSystemIds();
            DateTime?        earliest           = DateUtils.fromString(criteria.getEarliest());

            Collection <Event> events = loadEvents();

            foreach (Event Event in events)
            {
                //check user match if user specified
                bool userMatch = (user != null) ? user.Equals(Event.GetUser()) : true;

                //check detection system match if detection systems specified
                bool detectionSystemMatch = (detectionSystemIds != null && detectionSystemIds.Count > 0) ?
                                            detectionSystemIds.Contains(Event.GetDetectionSystemId()) : true;

                //check detection point match if detection point specified
                bool detectionPointMatch = (detectionPoint != null) ?
                                           detectionPoint.getId().Equals(Event.GetDetectionPoint().getId()) : true;

                bool earliestMatch = (earliest != null) ? earliest < DateUtils.fromString(Event.GetTimestamp()) : true;

                if (userMatch && detectionSystemMatch && detectionPointMatch && earliestMatch)
                {
                    matches.Add(Event);
                }
            }

            return(matches);
        }
        /**
         * Find/generate {@link Response} appropriate for specified {@link Attack}.
         *
         * @param attack {@link Attack} that is being analyzed
         * @return {@link Response} to be executed for given {@link Attack}
         */
        protected Response findAppropriateResponse(Attack attack)
        {
            DetectionPoint triggeringDetectionPoint = attack.GetDetectionPoint();

            SearchCriteria criteria = new SearchCriteria().
                                      setUser(attack.GetUser()).
                                      setDetectionPoint(triggeringDetectionPoint).
                                      setDetectionSystemIds(appSensorServer.getConfiguration().getRelatedDetectionSystems(attack.GetDetectionSystemId()));

            //grab any existing responses
            Collection <Response> existingResponses = appSensorServer.getResponseStore().findResponses(criteria);

            string   responseAction = null;
            Interval interval       = null;

            Collection <Response> possibleResponses = findPossibleResponses(triggeringDetectionPoint);

            //if (existingResponses == null || existingResponses.Size() == 0) {
            if (existingResponses == null || existingResponses.Count == 0)
            {
                //no responses yet, just grab first configured response from detection point
                // Response response = possibleResponses.iterator().next();
                IEnumerator <Response> enumerator = possibleResponses.GetEnumerator();
                enumerator.MoveNext();
                Response response = enumerator.Current;

                responseAction = response.getAction();
                interval       = response.getInterval();
            }
            else
            {
                foreach (Response configuredResponse in possibleResponses)
                {
                    responseAction = configuredResponse.getAction();
                    interval       = configuredResponse.getInterval();

                    if (!isPreviousResponse(configuredResponse, existingResponses))
                    {
                        //if we find that this response doesn't already exist, use it
                        break;
                    }

                    //if we reach here, we will just use the last configured response (repeat last response)
                }
            }

            if (responseAction == null)
            {
                //throw new IllegalArgumentException("No appropriate response was configured for this detection point: " + triggeringDetectionPoint.getId());
                throw new ArgumentException("No appropriate response was configured for this detection point: " + triggeringDetectionPoint.getId());
            }

            Response responses = new Response();

            responses.setUser(attack.GetUser());
            responses.setTimestamp(attack.GetTimestamp());
            responses.setAction(responseAction);
            responses.setInterval(interval);
            responses.setDetectionSystemId(attack.GetDetectionSystemId());

            return(responses);
        }
	/**
	 * Lookup configured {@link Response} objects for specified {@link DetectionPoint}
	 * 
	 * @param triggeringDetectionPoint {@link DetectionPoint} that triggered {@link Attack}
	 * @return collection of {@link Response} objects for given {@link DetectionPoint}
	 */
    protected Collection<Response> findPossibleResponses(DetectionPoint triggeringDetectionPoint) {
		//Collection<Response> possibleResponses = new List<Response>();
        Collection<Response> possibleResponses = new Collection<Response>();
		
		foreach (DetectionPoint configuredDetectionPoint in appSensorServer.getConfiguration().getDetectionPoints()) {
			if (configuredDetectionPoint.getId().Equals(triggeringDetectionPoint.getId())) {
				possibleResponses = configuredDetectionPoint.getResponses();
				break;
			}
		}
		return possibleResponses;
	}