This method merges together assignment data for the same day.

@param calendar current calendar
@param list assignment data
771767
private void mergeSameDay(ProjectCalendar calendar, LinkedList<TimephasedWork> list)
   {
      LinkedList<TimephasedWork> result = new LinkedList<TimephasedWork>();

      TimephasedWork previousAssignment = null;
      for (TimephasedWork assignment : list)
      {
         if (previousAssignment == null)
         {
            assignment.setAmountPerDay(assignment.getTotalAmount());
            result.add(assignment);
         }
         else
         {
            Date previousAssignmentStart = previousAssignment.getStart();
            Date previousAssignmentStartDay = DateHelper.getDayStartDate(previousAssignmentStart);
            Date assignmentStart = assignment.getStart();
            Date assignmentStartDay = DateHelper.getDayStartDate(assignmentStart);

            if (previousAssignmentStartDay.getTime() == assignmentStartDay.getTime())
            {
               Duration previousAssignmentWork = previousAssignment.getTotalAmount();
               Duration assignmentWork = assignment.getTotalAmount();

               if (previousAssignmentWork.getDuration() != 0 && assignmentWork.getDuration() == 0)
               {
                  continue;
               }

               result.removeLast();

               if (previousAssignmentWork.getDuration() != 0 && assignmentWork.getDuration() != 0)
               {
                  double work = previousAssignment.getTotalAmount().getDuration();
                  work += assignment.getTotalAmount().getDuration();
                  Duration totalWork = Duration.getInstance(work, TimeUnit.MINUTES);

                  TimephasedWork merged = new TimephasedWork();
                  merged.setStart(previousAssignment.getStart());
                  merged.setFinish(assignment.getFinish());
                  merged.setTotalAmount(totalWork);
                  assignment = merged;
               }
               else
               {
                  if (assignmentWork.getDuration() == 0)
                  {
                     assignment = previousAssignment;
                  }
               }
            }

            assignment.setAmountPerDay(assignment.getTotalAmount());
            result.add(assignment);
         }

         Duration calendarWork = calendar.getWork(assignment.getStart(), assignment.getFinish(), TimeUnit.MINUTES);
         Duration assignmentWork = assignment.getTotalAmount();
         if (calendarWork.getDuration() == 0 && assignmentWork.getDuration() == 0)
         {
            result.removeLast();
         }
         else
         {
            previousAssignment = assignment;
         }
      }

      list.clear();
      list.addAll(result);
   }
1088218
private void processWorkingHours(ProjectCalendar mpxjCalendar, Sequence uniqueID, Day day, List<OverriddenDayType> typeList)
   {
      if (isWorkingDay(mpxjCalendar, day))
      {
         ProjectCalendarHours mpxjHours = mpxjCalendar.getCalendarHours(day);
         if (mpxjHours != null)
         {
            OverriddenDayType odt = m_factory.createOverriddenDayType();
            typeList.add(odt);
            odt.setId(getIntegerString(uniqueID.next()));
            List<Interval> intervalList = odt.getInterval();
            for (DateRange mpxjRange : mpxjHours)
            {
               Date rangeStart = mpxjRange.getStart();
               Date rangeEnd = mpxjRange.getEnd();

               if (rangeStart != null && rangeEnd != null)
               {
                  Interval interval = m_factory.createInterval();
                  intervalList.add(interval);
                  interval.setStart(getTimeString(rangeStart));
                  interval.setEnd(getTimeString(rangeEnd));
               }
            }
         }
      }
   }
51340
public void setList(List<T> list) {
        if (list != mList) {
            mList = list;
            if (mList == null) {
                notifyInvalidated();
            } else {
                notifyChanged();
            }
        }
    }
1252015
private void processExceptionDays(ProjectCalendar mpxjCalendar, List<net.sf.mpxj.planner.schema.Day> dayList)
   {
      for (ProjectCalendarException mpxjCalendarException : mpxjCalendar.getCalendarExceptions())
      {
         Date rangeStartDay = mpxjCalendarException.getFromDate();
         Date rangeEndDay = mpxjCalendarException.getToDate();
         if (DateHelper.getDayStartDate(rangeStartDay).getTime() == DateHelper.getDayEndDate(rangeEndDay).getTime())
         {
            //
            // Exception covers a single day
            //
            net.sf.mpxj.planner.schema.Day day = m_factory.createDay();
            dayList.add(day);
            day.setType("day-type");
            day.setDate(getDateString(mpxjCalendarException.getFromDate()));
            day.setId(mpxjCalendarException.getWorking() ? "0" : "1");
         }
         else
         {
            //
            // Exception covers a range of days
            //
            Calendar cal = DateHelper.popCalendar(rangeStartDay);

            while (cal.getTime().getTime() < rangeEndDay.getTime())
            {
               net.sf.mpxj.planner.schema.Day day = m_factory.createDay();
               dayList.add(day);
               day.setType("day-type");
               day.setDate(getDateString(cal.getTime()));
               day.setId(mpxjCalendarException.getWorking() ? "0" : "1");
               cal.add(Calendar.DAY_OF_YEAR, 1);
            }
            
            DateHelper.pushCalendar(cal);
         }

         /**
          * @TODO we need to deal with date ranges here
          */
      }
   }
688089
public void insertCalendar(GoogleCalendar calendar) throws IOException {
        com.google.api.services.calendar.model.Calendar cal;
        cal = converter.convert(calendar, com.google.api.services.calendar.model.Calendar.class);
        cal = dao.calendars().insert(cal).execute();
        calendar.setId(cal.getId());
    }
1312039
protected final void listUpdate(List list, int index, Object value) {
        Object converted = value;

        if(list.size() > index) {
            Object o = list.get(index);
            // can only convert types when there is an item in the currently requested place
            if(o != null) {
                Class itemType = o.getClass();
                converted = ParseUtils.convertType(value, itemType);
            }

            list.set(index, value);
        } else {
            // @note: not sure that this is the right thing.  Question is whether or not to insert nulls here to fill list up to "index"
            // @update: List doesn't guarantee that implementations will accept nulls.  So, we can't rely on that as a solution.
            // @update: this is an unfortunate but necessary solution...unless the List has enough elements to 
            // accomodate the new item at a particular index, this must be an error case.  The reasons are this:
            // 1) can't fill the list with nulls, List implementations are allowed to disallow them
            // 2) can't just do an "add" to the list -- in processing [0] and [1] on an empty list, [1] may get processed first. 
            //    this will go into list slot [0].  then, [0] gets processed and simply overwrites the previous because it's 
            //    already in the list
            // 3) can't go to a mixed approach because there's no metadata about what has been done and no time to build
            //    something that is apt to be complicated and exposed to the user
            // so...
            // the ultimate 8.1sp2 functionality is to simply disallow updating a value in a list that doesn't exist.  that 
            // being said, it is still possible to simply add to the list.  if {actionForm.list[42]} inserts into the 42'nd 
            // item, {actionForm.list} will just do an append on POST since there is no index specified.  this fix does 
            // not break backwards compatability because it will work on full lists and is completely broken now on empty 
            // lists, so changing this just gives a better exception message that "ArrayIndexOutOfBounds".  :)
            // 
            // September 2, 2003
            // ekoneil@apache.com
            // 
            String msg = "An error occurred setting a value at index \"" +
                index +
                "\" because the list is " +
                (list != null ? (" of size " + list.size()) : "null") + ".  " +
                "Be sure to allocate enough items in the List to accomodate any updates which may occur against the list.";

            LOGGER.error(msg);
            throw new RuntimeException(msg);
        }
    }
239276
private void readCalendar(Calendar calendar)
   {
      // Create the calendar
      ProjectCalendar mpxjCalendar = m_projectFile.addCalendar();
      mpxjCalendar.setName(calendar.getName());

      // Default all days to working
      for (Day day : Day.values())
      {
         mpxjCalendar.setWorkingDay(day, true);
      }

      // Mark non-working days
      List<NonWork> nonWorkingDays = calendar.getNonWork();
      for (NonWork nonWorkingDay : nonWorkingDays)
      {
         // TODO: handle recurring exceptions
         if (nonWorkingDay.getType().equals("internal_weekly"))
         {
            mpxjCalendar.setWorkingDay(nonWorkingDay.getWeekday(), false);
         }
      }

      // Add default working hours for working days
      for (Day day : Day.values())
      {
         if (mpxjCalendar.isWorkingDay(day))
         {
            ProjectCalendarHours hours = mpxjCalendar.addCalendarHours(day);
            hours.addRange(ProjectCalendarWeek.DEFAULT_WORKING_MORNING);
            hours.addRange(ProjectCalendarWeek.DEFAULT_WORKING_AFTERNOON);
         }
      }
   }
929956
final public void addPositions(Set<Integer> list) {
    int[] positions = ArrayUtils
        .toPrimitive(list.toArray(new Integer[list.size()]));
    addPositions(positions);
  }
489788
public void setList(List<?> list) {
		this.checkNull(list);
		this.list.add(list);
		this.type.add(List.class);
	}
664961
private void readCalendar(Calendar calendar)
   {
      ProjectCalendar mpxjCalendar = m_projectFile.addCalendar();
      mpxjCalendar.setName(calendar.getName());
      m_calendarMap.put(calendar.getID(), mpxjCalendar);

      for (WeekDay day : calendar.getWeekDays().getWeekDay())
      {
         readWeekDay(mpxjCalendar, day);
      }

      for (ExceptedDay day : calendar.getExceptedDays().getExceptedDay())
      {
         readExceptionDay(mpxjCalendar, day);
      }
   }
316300
private boolean isSplit(ProjectCalendar calendar, List<TimephasedWork> list)
   {
      boolean result = false;
      for (TimephasedWork assignment : list)
      {
         if (calendar != null && assignment.getTotalAmount().getDuration() == 0)
         {
            Duration calendarWork = calendar.getWork(assignment.getStart(), assignment.getFinish(), TimeUnit.MINUTES);
            if (calendarWork.getDuration() != 0)
            {
               result = true;
               break;
            }
         }
      }
      return result;
   }
413722
@SuppressWarnings("unchecked")
    public MergeObservableList<T> insertList(@NonNull ObservableList<? extends T> list) {
        list.addOnListChangedCallback(callback);
        int oldSize = size();
        lists.add(list);
        modCount += 1;
        if (!list.isEmpty()) {
            listeners.notifyInserted(this, oldSize, list.size());
        }
        return this;
    }
104582
private void processCalendarData(List<ProjectCalendar> calendars) throws SQLException
   {
      for (ProjectCalendar calendar : calendars)
      {
         processCalendarData(calendar, getRows("SELECT * FROM MSP_CALENDAR_DATA WHERE PROJ_ID=? AND CAL_UID=?", m_projectID, calendar.getUniqueID()));
      }
   }
213859
public static <T> List<T> merge(List<List<T>> list) {
        return list.stream().flatMap(Collection::stream).collect(Collectors.toList());
    }
563637
private void processCalendar(MapRow row)
   {
      ProjectCalendar calendar = m_project.addCalendar();

      Map<UUID, List<DateRange>> dayTypeMap = processDayTypes(row.getRows("DAY_TYPES"));

      calendar.setName(row.getString("NAME"));

      processRanges(dayTypeMap.get(row.getUUID("SUNDAY_DAY_TYPE")), calendar.addCalendarHours(Day.SUNDAY));
      processRanges(dayTypeMap.get(row.getUUID("MONDAY_DAY_TYPE")), calendar.addCalendarHours(Day.MONDAY));
      processRanges(dayTypeMap.get(row.getUUID("TUESDAY_DAY_TYPE")), calendar.addCalendarHours(Day.TUESDAY));
      processRanges(dayTypeMap.get(row.getUUID("WEDNESDAY_DAY_TYPE")), calendar.addCalendarHours(Day.WEDNESDAY));
      processRanges(dayTypeMap.get(row.getUUID("THURSDAY_DAY_TYPE")), calendar.addCalendarHours(Day.THURSDAY));
      processRanges(dayTypeMap.get(row.getUUID("FRIDAY_DAY_TYPE")), calendar.addCalendarHours(Day.FRIDAY));
      processRanges(dayTypeMap.get(row.getUUID("SATURDAY_DAY_TYPE")), calendar.addCalendarHours(Day.SATURDAY));

      for (MapRow assignment : row.getRows("DAY_TYPE_ASSIGNMENTS"))
      {
         Date date = assignment.getDate("DATE");
         processRanges(dayTypeMap.get(assignment.getUUID("DAY_TYPE_UUID")), calendar.addCalendarException(date, date));
      }

      m_calendarMap.put(row.getUUID("UUID"), calendar);
   }
99855
private void splitDays(ProjectCalendar calendar, LinkedList<TimephasedWork> list)
   {
      LinkedList<TimephasedWork> result = new LinkedList<TimephasedWork>();
      boolean remainderInserted = false;
      
      for (TimephasedWork assignment : list)
      {
         if (remainderInserted)
         {
            assignment.setStart(DateHelper.addDays(assignment.getStart(), 1));
            remainderInserted = false;
         }

         while (assignment != null)
         {
            Date startDay = DateHelper.getDayStartDate(assignment.getStart());
            Date finishDay = DateHelper.getDayStartDate(assignment.getFinish());

            // special case - when the finishday time is midnight, it's really the previous day...
            if (assignment.getFinish().getTime() == finishDay.getTime())
            {
               finishDay = DateHelper.addDays(finishDay, -1);
            }

            if (startDay.getTime() == finishDay.getTime())
            {
               Duration totalWork = assignment.getTotalAmount();
               Duration assignmentWork = getAssignmentWork(calendar, assignment);
               if ((totalWork.getDuration() - assignmentWork.getDuration()) > EQUALITY_DELTA)
               {
                  assignment.setTotalAmount(assignmentWork);
                  result.add(assignment);
                  Duration remainingWork = Duration.getInstance(totalWork.getDuration() - assignmentWork.getDuration(), TimeUnit.MINUTES);
                  
                  Date remainderStart = DateHelper.addDays(finishDay, 1);
                  Date remainderFinish = DateHelper.addDays(remainderStart, 1);
                  
                  TimephasedWork remainder = new TimephasedWork();
                  remainder.setStart(remainderStart);
                  remainder.setFinish(remainderFinish);
                  remainder.setTotalAmount(remainingWork);
                  result.add(remainder);

                  remainderInserted = true;
               }
               else
               {
                  result.add(assignment);
               }
               break;
            }

            TimephasedWork[] split = splitFirstDay(calendar, assignment);
            if (split[0] != null)
            {
               result.add(split[0]);
            }

            if (assignment.equals(split[1]))
            {
               break;
            }

            assignment = split[1];
         }
      }
     
      list.clear();
      list.addAll(result);
   }
255445
public void setCalendar(ProjectCalendar calendar)
   {
      set(TaskField.CALENDAR, calendar);
      setCalendarUniqueID(calendar == null ? null : calendar.getUniqueID());
   }