/// <summary>
 /// Check that data is valid.
 /// </summary>
 /// <param name="dateTimeInterval">DateTime interval.</param>
 /// <param name="checkBeginEnd">
 /// Indicates if Begin must have a lower value than End.
 /// </param>
 public static void CheckData(this WebDateTimeInterval dateTimeInterval, Boolean checkBeginEnd)
 {
     if (dateTimeInterval.IsNotNull())
     {
         if (checkBeginEnd && (dateTimeInterval.Begin.Ticks > dateTimeInterval.End.Ticks))
         {
             throw new ArgumentException(
                       "Begin must be older than End. Begin = " + Convert.ToString(dateTimeInterval.Begin) + " End = "
                       + Convert.ToString(dateTimeInterval.End));
         }
     }
 }
        /// <summary>
        /// Get string filter to be used with Elasticsearch.
        /// </summary>
        /// <param name="searchCriteria">Search criteria.</param>
        /// <param name="startDateTimeColumn">Name of the field with a start DateTime value.</param>
        /// <param name="endDateTimeColumn">Name of the field with a end DateTime value.</param>
        /// <param name="accuracyColumn">Name of the field with an observation date time accuracy value.</param>
        /// <param name="compareOperator">
        /// Operator that should be used between this date time
        /// interval search criteria and the data that it is compared to.
        /// Operator must be set to CompareOperator:Excluding or
        /// CompareOperator:Including.
        /// </param>
        /// <returns>String filter.</returns>
        public static String GetFilter(this WebDateTimeInterval searchCriteria,
                                       String startDateTimeColumn,
                                       String endDateTimeColumn,
                                       String accuracyColumn,
                                       CompareOperator compareOperator)
        {
            Int64         accuracyInSeconds;
            StringBuilder filter;

            filter = new StringBuilder();
            if (searchCriteria.IsNotNull())
            {
#if !SWEDISH_SPECIES_OBSERVATION_SOAP_SERVICE
                if (compareOperator == CompareOperator.Excluding)
                {
                    filter.Append("{\"bool\":{ \"must\" : [");

                    if (searchCriteria.IsDayOfYearSpecified)
                    {
                        // Check if the interval is within a year.
                        if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                        {
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append(", \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");
                            filter.Append(",{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append(", \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");

                            // Remove observations with bad accuracy.
                            accuracyInSeconds = (searchCriteria.End.DayOfYear - searchCriteria.Begin.DayOfYear + 1) * 86400;
                            filter.Append(",{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"lte\": " + accuracyInSeconds);
                            filter.Append("}}}");
                        }
                        else
                        {
                            // If the interval is not within a year.
                            filter.Append("{\"bool\":{ \"should\" : [");
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append("}}}");
                            filter.Append(",{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");
                            filter.Append("]}}");

                            filter.Append(",{\"bool\":{ \"should\" : [");
                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append("}}}");
                            filter.Append(",{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");
                            filter.Append("]}}");

                            // Remove observations with bad accuracy.
                            accuracyInSeconds = (searchCriteria.End.DayOfYear + 366 - searchCriteria.Begin.DayOfYear) * 86400;
                            filter.Append(",{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"lte\": " + accuracyInSeconds);
                            filter.Append("}}}");
                        }
                    }
                    else
                    {
                        // Day of year is not specified.
                        // Use exact day and month value to compare with.

                        // Check if the interval is within a year.
                        if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                        {
                            // Handle start field compared to search criteria Begin.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}},"); // End OR.

                            // Handle start field compared to search criteria End.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}},"); // End OR.

                            // Handle end field compared to search criteria Begin.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}},"); // End OR.

                            // Handle end field compared to search criteria End.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");

                            filter.Append("]}}"); // End AND.
                            filter.Append("]}}"); // End OR.

                            // Remove observations with bad accuracy.
                            accuracyInSeconds = (searchCriteria.End.DayOfYear - searchCriteria.Begin.DayOfYear + 1) * 86400;
                            filter.Append(",{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"lte\": " + accuracyInSeconds);
                            filter.Append("}}}");
                        }
                        else
                        {
                            // Handle start field compared to search criteria Begin.
                            filter.Append("{\"bool\":{ \"should\" : [");
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}},"); // End OR.

                            // Handle start field compared to search criteria End.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}}");  // End OR.
                            filter.Append("]}},"); // End OR.

                            // Handle end field compared to search criteria Begin.
                            filter.Append("{\"bool\":{ \"should\" : [");
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");

                            filter.Append("]}}");  // End AND.
                            filter.Append("]}},"); // End OR.

                            // Handle end field compared to search criteria End.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");

                            filter.Append("]}}"); // End AND.
                            filter.Append("]}}"); // End OR.
                            filter.Append("]}}"); // End OR.

                            // Remove observations with bad accuracy.
                            accuracyInSeconds = (searchCriteria.End.DayOfYear + 366 - searchCriteria.Begin.DayOfYear) * 86400;
                            filter.Append(",{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"lte\": " + accuracyInSeconds);
                            filter.Append("}}}");
                        }
                    }

                    filter.Append("]}}"); // End AND.
                }

                if (compareOperator == CompareOperator.Including)
                {
                    if (searchCriteria.IsDayOfYearSpecified)
                    {
                        // Check if the interval is within a year.
                        if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                        {
                            // If the interval is within a year.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append(", \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}, ");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append(", \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append("}}}");
                            filter.Append(",{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");
                            filter.Append("]}}, ");

                            // Add observations with bad accuracy.
                            accuracyInSeconds = 366 * 86400;
                            filter.Append("{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"gte\": " + accuracyInSeconds);
                            filter.Append("}}}");

                            filter.Append("]}}");
                        }
                        else
                        {
                            // If the interval is not within a year.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append("}}}");

                            filter.Append(",{ \"range\": {\"" + startDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");

                            filter.Append(",{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                            filter.Append("}}}");

                            filter.Append(",{ \"range\": {\"" + endDateTimeColumn + "_DayOfYear\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                            filter.Append("}}}");

                            filter.Append(",{ \"script\": {");
                            filter.Append(" \"script\": \"doc['" + startDateTimeColumn + "_DayOfYear'].value > ");
                            filter.Append("doc['" + endDateTimeColumn + "_DayOfYear'].value\"");
                            filter.Append("}}");

                            // Add observations with bad accuracy.
                            accuracyInSeconds = 366 * 86400;
                            filter.Append(",{ \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"gte\": " + accuracyInSeconds);
                            filter.Append("}}}");

                            filter.Append("]}}");
                        }
                    }
                    else
                    {
                        // Day of year is not specified.
                        // Use exact day and month value to compare with.

                        // Check if the interval is within a year.
                        if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                        {
                            filter.Append("{\"bool\":{ \"should\" : [");

                            // Check if start is inside of search criteria.
                            filter.Append("{\"bool\":{ \"must\" : [");

                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.

                            filter.Append(", {\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.
                            filter.Append("]}}"); // End AND.

                            // Check if end is inside of search criteria.
                            filter.Append(", {\"bool\":{ \"must\" : [");

                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append(" { \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.

                            filter.Append(", {\"bool\":{ \"should\" : [");

                            filter.Append(" { \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.
                            filter.Append("]}}"); // End AND.

                            // Check if start and end covers the entire search criteria.
                            filter.Append(", {\"bool\":{ \"must\" : [");

                            filter.Append("{\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lt\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.

                            filter.Append(", {\"bool\":{ \"should\" : [");

                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.End.Month);
                            filter.Append("}}}, ");

                            filter.Append("{\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}, ");
                            filter.Append("{ \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gt\": " + searchCriteria.End.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append("]}}"); // End OR.
                            filter.Append("]}}"); // End AND.

                            // Add observations with bad accuracy.
                            accuracyInSeconds = 366 * 86400;
                            filter.Append(", { \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"gte\": " + accuracyInSeconds);
                            filter.Append("}}}");

                            filter.Append("]}}"); // End OR.
                        }
                        else
                        {
                            // Interval is not within a year.
                            filter.Append("{\"bool\":{ \"should\" : [");

                            // Check if start is inside of search criteria.
                            filter.Append("{ \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}");

                            filter.Append(", {\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}");
                            filter.Append(", { \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append(", { \"range\": {\"" + startDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}");

                            filter.Append(", {\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + startDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}");
                            filter.Append(", { \"range\": {\"" + startDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            // Check if end is inside of search criteria.
                            filter.Append(", { \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                            filter.Append("}}}");

                            filter.Append(", {\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.Begin.Month);
                            filter.Append("}}");
                            filter.Append(", { \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            filter.Append(", { \"range\": {\"" + endDateTimeColumn + "_MonthOfYear\": {");
                            filter.Append(" \"lt\": " + searchCriteria.End.Month);
                            filter.Append("}}}");

                            filter.Append(", {\"bool\":{ \"must\" : [");
                            filter.Append("{ \"term\": {\"" + endDateTimeColumn + "_MonthOfYear\": ");
                            filter.Append(searchCriteria.End.Month);
                            filter.Append("}}");
                            filter.Append(", { \"range\": {\"" + endDateTimeColumn + "_DayOfMonth\": {");
                            filter.Append(" \"lte\": " + searchCriteria.End.Day);
                            filter.Append("}}}");
                            filter.Append("]}}"); // End AND.

                            // Check if start and end covers the entire search criteria.
                            filter.Append(",{ \"script\": {");
                            filter.Append(" \"script\": \"doc['" + startDateTimeColumn + "_MonthOfYear'].value > ");
                            filter.Append("doc['" + endDateTimeColumn + "_MonthOfYear'].value\"");
                            filter.Append("}}");

                            filter.Append(", {\"bool\":{ \"must\" : [");
                            filter.Append("{ \"script\": {");
                            filter.Append(" \"script\": \"doc['" + startDateTimeColumn + "_MonthOfYear'].value == ");
                            filter.Append("doc['" + endDateTimeColumn + "_MonthOfYear'].value\"");
                            filter.Append("}}");
                            filter.Append(",{ \"script\": {");
                            filter.Append(" \"script\": \"doc['" + startDateTimeColumn + "_DayOfMonth'].value > ");
                            filter.Append("doc['" + endDateTimeColumn + "_DayOfMonth'].value\"");
                            filter.Append("}}");
                            filter.Append("]}}"); // End AND.

                            // Add observations with bad accuracy.
                            accuracyInSeconds = 366 * 86400;
                            filter.Append(", { \"range\": {\"" + accuracyColumn + "\": {");
                            filter.Append(" \"gte\": " + accuracyInSeconds);
                            filter.Append("}}}");

                            filter.Append("]}}"); // End OR.
                        }
                    }
                }
#endif
            }

            return(filter.ToString());
        }
        /// <summary>
        /// Get string filter to be used with Elasticsearch.
        /// </summary>
        /// <param name="searchCriteria">Search criteria.</param>
        /// <param name="dateTimeColumn">Name of the field with a DateTime value.</param>
        /// <returns>String filter.</returns>
        public static String GetFilter(this WebDateTimeInterval searchCriteria, String dateTimeColumn)
        {
            StringBuilder filter;

            filter = new StringBuilder();
            if (searchCriteria.IsNotNull())
            {
#if !SWEDISH_SPECIES_OBSERVATION_SOAP_SERVICE
                if (searchCriteria.IsDayOfYearSpecified)
                {
                    // Check if the interval is within a year.
                    if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                    {
                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfYear\": {");
                        filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear + ",");
                        filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                        filter.Append("}}}");
                    }
                    else
                    {
                        // If the interval is not within a year.
                        filter.Append("{\"bool\":{ \"should\" : [");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfYear\": {");
                        filter.Append(" \"gte\": " + searchCriteria.Begin.DayOfYear);
                        filter.Append("}}}, ");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfYear\": {");
                        filter.Append(" \"lte\": " + searchCriteria.End.DayOfYear);
                        filter.Append("}}}");

                        filter.Append("]}}");
                    }
                }
                else
                {
                    // Day of year is not specified.
                    // Use exact day and month value to compare with.

                    // Check if the interval is within a year.
                    if (searchCriteria.Begin.DayOfYear <= searchCriteria.End.DayOfYear)
                    {
                        // Handle search criteria Begin.
                        filter.Append("{\"bool\":{ \"should\" : [");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_MonthOfYear\": {");
                        filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                        filter.Append("}}}, ");

                        filter.Append("{\"bool\":{ \"must\" : [");

                        filter.Append("{ \"term\": {\"" + dateTimeColumn + "_MonthOfYear\": ");
                        filter.Append(searchCriteria.Begin.Month);
                        filter.Append("}}, ");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfMonth\": {");
                        filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                        filter.Append("}}}");

                        filter.Append("]}}");  // End AND.
                        filter.Append("]}},"); // End OR.

                        // Handle search criteria End.
                        filter.Append("{\"bool\":{ \"should\" : [");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_MonthOfYear\": {");
                        filter.Append(" \"lt\": " + searchCriteria.End.Month);
                        filter.Append("}}}, ");

                        filter.Append("{\"bool\":{ \"must\" : [");

                        filter.Append("{ \"term\": {\"" + dateTimeColumn + "_MonthOfYear\": ");
                        filter.Append(searchCriteria.End.Month);
                        filter.Append("}}, ");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfMonth\": {");
                        filter.Append(" \"lte\": " + searchCriteria.End.Day);
                        filter.Append("}}}");

                        filter.Append("]}}"); // End AND.
                        filter.Append("]}}"); // End OR.
                    }
                    else
                    {
                        // If the interval is not within a year.
                        // Handle search criteria Begin.
                        filter.Append("{\"bool\":{ \"should\" : [");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_MonthOfYear\": {");
                        filter.Append(" \"gt\": " + searchCriteria.Begin.Month);
                        filter.Append("}}}, ");

                        filter.Append("{\"bool\":{ \"must\" : [");

                        filter.Append("{ \"term\": {\"" + dateTimeColumn + "_MonthOfYear\": ");
                        filter.Append(searchCriteria.Begin.Month);
                        filter.Append("}}, ");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfMonth\": {");
                        filter.Append(" \"gte\": " + searchCriteria.Begin.Day);
                        filter.Append("}}}");

                        filter.Append("]}}, "); // End AND.

                        // Handle search criteria End.
                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_MonthOfYear\": {");
                        filter.Append(" \"lt\": " + searchCriteria.End.Month);
                        filter.Append("}}}, ");

                        filter.Append("{\"bool\":{ \"must\" : [");

                        filter.Append("{ \"term\": {\"" + dateTimeColumn + "_MonthOfYear\": ");
                        filter.Append(searchCriteria.End.Month);
                        filter.Append("}}, ");

                        filter.Append("{ \"range\": {\"" + dateTimeColumn + "_DayOfMonth\": {");
                        filter.Append(" \"lte\": " + searchCriteria.End.Day);
                        filter.Append("}}}");

                        filter.Append("]}}"); // End AND.
                        filter.Append("]}}"); // End OR.
                    }
                }
#endif
            }

            return(filter.ToString());
        }