private void processTaskData() throws IOException
   {
      FieldMap fieldMap = new FieldMap14(m_file.getProjectProperties(), m_file.getCustomFields());
      fieldMap.createTaskFieldMap(m_projectProps);

      FieldMap enterpriseCustomFieldMap = new FieldMap14(m_file.getProjectProperties(), m_file.getCustomFields());
      enterpriseCustomFieldMap.createEnterpriseCustomFieldMap(m_projectProps, TaskField.class);

      DirectoryEntry taskDir = (DirectoryEntry) m_projectDir.getEntry("TBkndTask");
      VarMeta taskVarMeta = new VarMeta12(new DocumentInputStream(((DocumentEntry) taskDir.getEntry("VarMeta"))));
      Var2Data taskVarData = new Var2Data(taskVarMeta, new DocumentInputStream(((DocumentEntry) taskDir.getEntry("Var2Data"))));
      FixedMeta taskFixedMeta = new FixedMeta(new DocumentInputStream(((DocumentEntry) taskDir.getEntry("FixedMeta"))), 47);
      FixedData taskFixedData = new FixedData(taskFixedMeta, new DocumentInputStream(((DocumentEntry) taskDir.getEntry("FixedData"))), fieldMap.getMaxFixedDataSize(0));
      FixedMeta taskFixed2Meta = new FixedMeta(new DocumentInputStream(((DocumentEntry) taskDir.getEntry("Fixed2Meta"))), taskFixedData, 92, 93, 94);
      FixedData taskFixed2Data = new FixedData(taskFixed2Meta, new DocumentInputStream(((DocumentEntry) taskDir.getEntry("Fixed2Data"))));

      //      System.out.println(taskFixedMeta);
      //      System.out.println(taskFixedData);
      //      System.out.println(taskVarMeta);
      //      System.out.println(taskVarData);
      //      System.out.println(taskFixed2Meta);
      //      System.out.println(taskFixed2Data);
      //      System.out.println(m_outlineCodeVarData.getVarMeta());
      //      System.out.println(m_outlineCodeVarData);

      // Process aliases
      if (taskDir.hasEntry("Props"))
      {
         Props14 props = new Props14(m_inputStreamFactory.getInstance(taskDir, "Props"));
         new CustomFieldAliasReader(m_file.getCustomFields(), props.getByteArray(TASK_FIELD_NAME_ALIASES)).process();
      }
      
      TreeMap<Integer, Integer> taskMap = createTaskMap(fieldMap, taskFixedMeta, taskFixedData, taskVarData);
      // The var data may not contain all the tasks as tasks with no var data assigned will
      // not be saved in there. Most notably these are tasks with no name. So use the task map
      // which contains all the tasks.
      Object[] uniqueIdArray = taskMap.keySet().toArray(); //taskVarMeta.getUniqueIdentifierArray();
      Integer offset;
      byte[] data;
      byte[] metaData;
      byte[] metaData2;
      Task task;
      boolean autoWBS = true;
      LinkedList<Task> externalTasks = new LinkedList<Task>();
      RecurringTaskReader recurringTaskReader = null;
      String notes;

      //
      // Select the correct meta data locations depending on
      // which version of Microsoft project generated this file
      //
      MppBitFlag[] metaDataBitFlags;
      MppBitFlag[] metaData2BitFlags;
      if (NumberHelper.getInt(m_file.getProjectProperties().getApplicationVersion()) > ApplicationVersion.PROJECT_2010)
      {
         metaDataBitFlags = PROJECT2013_TASK_META_DATA_BIT_FLAGS;
         metaData2BitFlags = PROJECT2013_TASK_META_DATA2_BIT_FLAGS;
      }
      else
      {
         metaDataBitFlags = PROJECT2010_TASK_META_DATA_BIT_FLAGS;
         metaData2BitFlags = PROJECT2010_TASK_META_DATA2_BIT_FLAGS;
      }

      for (int loop = 0; loop < uniqueIdArray.length; loop++)
      {
         Integer uniqueID = (Integer) uniqueIdArray[loop];

         offset = taskMap.get(uniqueID);
         if (taskFixedData.isValidOffset(offset) == false)
         {
            continue;
         }

         data = taskFixedData.getByteArrayValue(offset.intValue());
         metaData = taskFixedMeta.getByteArrayValue(offset.intValue());
         Integer id = Integer.valueOf(MPPUtility.getInt(data, fieldMap.getFixedDataOffset(TaskField.ID)));

         if (data.length == NULL_TASK_BLOCK_SIZE)
         {
            task = m_file.addTask();
            task.setNull(true);
            task.setUniqueID(Integer.valueOf(MPPUtility.getInt(data, TASK_UNIQUE_ID_FIXED_OFFSET)));
            task.setID(Integer.valueOf(MPPUtility.getInt(data, TASK_ID_FIXED_OFFSET)));
            m_nullTaskOrder.put(task.getID(), task.getUniqueID());
            continue;
         }

         if (data.length < fieldMap.getMaxFixedDataSize(0))
         {
            byte[] newData = new byte[fieldMap.getMaxFixedDataSize(0) + 8];
            System.arraycopy(data, 0, newData, 0, data.length);
            data = newData;
         }

         //System.out.println (ByteArrayHelper.hexdump(data, false, 16, ""));
         //System.out.println (ByteArrayHelper.hexdump(data,false));
         //System.out.println (ByteArrayHelper.hexdump(metaData, false, 16, ""));
         //MPPUtility.dataDump(m_file, data, false, false, false, true, false, false, false, false);
         //MPPUtility.dataDump(metaData, true, true, true, true, true, true, true);
         //MPPUtility.varDataDump(taskVarData, id, true, true, true, true, true, true);

         metaData2 = taskFixed2Meta.getByteArrayValue(offset.intValue());
         byte[] data2 = taskFixed2Data.getByteArrayValue(offset.intValue());
         //System.out.println (ByteArrayHelper.hexdump(metaData2, false, 16, ""));
         //System.out.println(ByteArrayHelper.hexdump(data2, false, 16, ""));
         //System.out.println (ByteArrayHelper.hexdump(metaData2,false));

         byte[] recurringData = taskVarData.getByteArray(uniqueID, fieldMap.getVarDataKey(TaskField.RECURRING_DATA));

         Task temp = m_file.getTaskByID(id);
         if (temp != null)
         {
            // Task with this id already exists... determine if this is the 'real' task by seeing
            // if this task has some var data. This is sort of hokey, but it's the best method i have
            // been able to see.
            if (!taskVarMeta.getUniqueIdentifierSet().contains(uniqueID))
            {
               // Sometimes Project contains phantom tasks that coexist on the same id as a valid
               // task. In this case don't want to include the phantom task. Seems to be a very rare case.
               continue;
            }
            else
               if (temp.getName() == null)
               {
                  // Ok, this looks valid. Remove the previous instance since it is most likely not a valid task.
                  // At worst case this removes a task with an empty name.
                  m_file.removeTask(temp);
               }
         }
         task = m_file.addTask();

         task.disableEvents();

         fieldMap.populateContainer(TaskField.class, task, uniqueID, new byte[][]
         {
            data,
            data2
         }, taskVarData);

         enterpriseCustomFieldMap.populateContainer(TaskField.class, task, uniqueID, null, taskVarData);

         task.enableEvents();

         task.setEstimated(getDurationEstimated(MPPUtility.getShort(data, fieldMap.getFixedDataOffset(TaskField.ACTUAL_DURATION_UNITS))));

         Integer externalTaskID = task.getSubprojectTaskID();
         if (externalTaskID != null && externalTaskID.intValue() != 0)
         {
            task.setExternalTask(true);
            externalTasks.add(task);
         }

         processHyperlinkData(task, taskVarData.getByteArray(uniqueID, fieldMap.getVarDataKey(TaskField.HYPERLINK_DATA)));

         task.setID(id);

         task.setOutlineCode(1, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE1_INDEX)));
         task.setOutlineCode(2, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE2_INDEX)));
         task.setOutlineCode(3, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE3_INDEX)));
         task.setOutlineCode(4, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE4_INDEX)));
         task.setOutlineCode(5, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE5_INDEX)));
         task.setOutlineCode(6, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE6_INDEX)));
         task.setOutlineCode(7, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE7_INDEX)));
         task.setOutlineCode(8, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE8_INDEX)));
         task.setOutlineCode(9, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE9_INDEX)));
         task.setOutlineCode(10, getCustomFieldOutlineCodeValue(taskVarData, m_outlineCodeVarData, uniqueID, fieldMap.getVarDataKey(TaskField.OUTLINE_CODE10_INDEX)));

         task.setRecurring(MPPUtility.getShort(data, 40) == 2);

         task.setUniqueID(uniqueID);

         task.setExpanded(((metaData[12] & 0x02) == 0));
         readBitFields(metaDataBitFlags, task, metaData);
         readBitFields(metaData2BitFlags, task, metaData2);

         m_parentTasks.put(task.getUniqueID(), (Integer) task.getCachedValue(TaskField.PARENT_TASK_UNIQUE_ID));

         if (task.getStart() == null || (task.getCachedValue(TaskField.SCHEDULED_START) != null && task.getTaskMode() == TaskMode.AUTO_SCHEDULED))
         {
            task.setStart((Date) task.getCachedValue(TaskField.SCHEDULED_START));
         }

         if (task.getFinish() == null || (task.getCachedValue(TaskField.SCHEDULED_FINISH) != null && task.getTaskMode() == TaskMode.AUTO_SCHEDULED))
         {
            task.setFinish((Date) task.getCachedValue(TaskField.SCHEDULED_FINISH));
         }

         if (task.getDuration() == null || (task.getCachedValue(TaskField.SCHEDULED_DURATION) != null && task.getTaskMode() == TaskMode.AUTO_SCHEDULED))
         {
            task.setDuration((Duration) task.getCachedValue(TaskField.SCHEDULED_DURATION));
         }

         switch (task.getConstraintType())
         {
            //
            // Adjust the start and finish dates if the task
            // is constrained to start as late as possible.
            //
            case AS_LATE_AS_POSSIBLE:
            {
               if (DateHelper.compare(task.getStart(), task.getLateStart()) < 0)
               {
                  task.setStart(task.getLateStart());
               }
               if (DateHelper.compare(task.getFinish(), task.getLateFinish()) < 0)
               {
                  task.setFinish(task.getLateFinish());
               }
               break;
            }

            case START_NO_LATER_THAN:
            case FINISH_NO_LATER_THAN:
            {
               if (DateHelper.compare(task.getFinish(), task.getStart()) < 0)
               {
                  task.setFinish(task.getLateFinish());
               }
               break;
            }

            default:
            {
               break;
            }
         }

         //
         // Retrieve task recurring data
         //
         if (recurringData != null)
         {
            if (recurringTaskReader == null)
            {
               recurringTaskReader = new RecurringTaskReader(m_file.getProjectProperties());
            }
            recurringTaskReader.processRecurringTask(task, recurringData);
            task.setRecurring(true);
         }

         //
         // Retrieve the task notes.
         //
         notes = task.getNotes();
         if (m_reader.getPreserveNoteFormatting() == false)
         {
            notes = RtfHelper.strip(notes);
         }

         task.setNotes(notes);

         //
         // Set the calendar name
         //
         Integer calendarID = (Integer) task.getCachedValue(TaskField.CALENDAR_UNIQUE_ID);
         if (calendarID != null && calendarID.intValue() != -1)
         {
            ProjectCalendar calendar = m_file.getCalendarByUniqueID(calendarID);
            if (calendar != null)
            {
               task.setCalendar(calendar);
            }
         }

         //
         // Set the sub project flag
         //
         SubProject sp = m_taskSubProjects.get(task.getUniqueID());
         task.setSubProject(sp);

         //
         // Set the external flag
         //
         if (sp != null)
         {
            task.setExternalTask(sp.isExternalTask(task.getUniqueID()));
            if (task.getExternalTask())
            {
               task.setExternalTaskProject(sp.getFullPath());
            }
         }

         //
         // If we have a WBS value from the MPP file, don't autogenerate
         //
         if (task.getWBS() != null)
         {
            autoWBS = false;
         }

         //
         // If this is a split task, allocate space for the split durations
         //
         if ((metaData[9] & 0x80) == 0)
         {
            task.setSplits(new LinkedList<DateRange>());
         }

         //
         // If this is a manually scheduled task, read the manual duration
         //
         if (task.getTaskMode() != TaskMode.MANUALLY_SCHEDULED)
         {
            task.setManualDuration(null);
         }

         //
         // Process any enterprise columns
         //
         processTaskEnterpriseColumns(uniqueID, task, taskVarData, metaData2);

         // Unfortunately it looks like 'null' tasks sometimes make it through. So let's check for to see if we
         // need to mark this task as a null task after all.
         if (task.getName() == null && ((task.getStart() == null || task.getStart().getTime() == MPPUtility.getEpochDate().getTime()) || (task.getFinish() == null || task.getFinish().getTime() == MPPUtility.getEpochDate().getTime()) || (task.getCreateDate() == null || task.getCreateDate().getTime() == MPPUtility.getEpochDate().getTime())))
         {
            // Remove this to avoid passing bad data to the client
            m_file.removeTask(task);

            task = m_file.addTask();
            task.setNull(true);
            task.setUniqueID(uniqueID);
            task.setID(id);
            m_nullTaskOrder.put(task.getID(), task.getUniqueID());
            //System.out.println(task);
            continue;
         }

         if (data2 == null || data2.length < 24)
         {
            m_nullTaskOrder.put(task.getID(), task.getUniqueID());
         }
         else
         {
            Long key = Long.valueOf(MPPUtility.getLong(data2, 16));
            m_taskOrder.put(key, task.getUniqueID());
         }

         //System.out.println(task + " " + MPPUtility.getShort(data2, 22)); // JPI - looks like this value determines the ID order! Validate and check other versions!
         m_eventManager.fireTaskReadEvent(task);
         //dumpUnknownData(task.getUniqueID().toString(), UNKNOWN_TASK_DATA, data);
         //System.out.println(task);
      }

      //
      // Enable auto WBS if necessary
      //
      m_file.getProjectConfig().setAutoWBS(autoWBS);

      //
      // We have now read all of the task, so we are in a position
      // to perform post-processing to set up the relevant details
      // for each external task.
      //
      if (!externalTasks.isEmpty())
      {
         processExternalTasks(externalTasks);
      }
   }
private void processTaskData ( ) throws IOException { FieldMap fieldMap = new FieldMap14 ( m_file . getProjectProperties ( ) , m_file . getCustomFields ( ) ) ; fieldMap . createTaskFieldMap ( m_projectProps ) ; FieldMap enterpriseCustomFieldMap = new FieldMap14 ( m_file . getProjectProperties ( ) , m_file . getCustomFields ( ) ) ; enterpriseCustomFieldMap . createEnterpriseCustomFieldMap ( m_projectProps , TaskField . class ) ; DirectoryEntry taskDir = ( DirectoryEntry ) m_projectDir . getEntry ( "TBkndTask" ) ; VarMeta taskVarMeta = new VarMeta12 ( new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "VarMeta" ) ) ) ) ; Var2Data taskVarData = new Var2Data ( taskVarMeta , new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "Var2Data" ) ) ) ) ; FixedMeta taskFixedMeta = new FixedMeta ( new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "FixedMeta" ) ) ) , 47 ) ; FixedData taskFixedData = new FixedData ( taskFixedMeta , new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "FixedData" ) ) ) , fieldMap . getMaxFixedDataSize ( 0 ) ) ; FixedMeta taskFixed2Meta = new FixedMeta ( new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "Fixed2Meta" ) ) ) , taskFixedData , 92 , 93 , 94 ) ; FixedData taskFixed2Data = new FixedData ( taskFixed2Meta , new DocumentInputStream ( ( ( DocumentEntry ) taskDir . getEntry ( "Fixed2Data" ) ) ) ) ; if ( taskDir . hasEntry ( "Props" ) ) { Props14 props = new Props14 ( m_inputStreamFactory . getInstance ( taskDir , "Props" ) ) ; new CustomFieldAliasReader ( m_file . getCustomFields ( ) , props . getByteArray ( TASK_FIELD_NAME_ALIASES ) ) . process ( ) ; } TreeMap < Integer , Integer > taskMap = createTaskMap ( fieldMap , taskFixedMeta , taskFixedData , taskVarData ) ; Object [ ] uniqueIdArray = taskMap . keySet ( ) . toArray ( ) ; Integer offset ; byte [ ] data ; byte [ ] metaData ; byte [ ] metaData2 ; Task task ; boolean autoWBS = true ; LinkedList < Task > externalTasks = new LinkedList < Task > ( ) ; RecurringTaskReader recurringTaskReader = null ; String notes ; MppBitFlag [ ] metaDataBitFlags ; MppBitFlag [ ] metaData2BitFlags ; if ( NumberHelper . getInt ( m_file . getProjectProperties ( ) . getApplicationVersion ( ) ) > ApplicationVersion . PROJECT_2010 ) { metaDataBitFlags = PROJECT2013_TASK_META_DATA_BIT_FLAGS ; metaData2BitFlags = PROJECT2013_TASK_META_DATA2_BIT_FLAGS ; } else { metaDataBitFlags = PROJECT2010_TASK_META_DATA_BIT_FLAGS ; metaData2BitFlags = PROJECT2010_TASK_META_DATA2_BIT_FLAGS ; } for ( int loop = 0 ; loop < uniqueIdArray . length ; loop ++ ) { Integer uniqueID = ( Integer ) uniqueIdArray [ loop ] ; offset = taskMap . get ( uniqueID ) ; if ( taskFixedData . isValidOffset ( offset ) == false ) { continue ; } data = taskFixedData . getByteArrayValue ( offset . intValue ( ) ) ; metaData = taskFixedMeta . getByteArrayValue ( offset . intValue ( ) ) ; Integer id = Integer . valueOf ( MPPUtility . getInt ( data , fieldMap . getFixedDataOffset ( TaskField . ID ) ) ) ; if ( data . length == NULL_TASK_BLOCK_SIZE ) { task = m_file . addTask ( ) ; task . setNull ( true ) ; task . setUniqueID ( Integer . valueOf ( MPPUtility . getInt ( data , TASK_UNIQUE_ID_FIXED_OFFSET ) ) ) ; task . setID ( Integer . valueOf ( MPPUtility . getInt ( data , TASK_ID_FIXED_OFFSET ) ) ) ; m_nullTaskOrder . put ( task . getID ( ) , task . getUniqueID ( ) ) ; continue ; } if ( data . length < fieldMap . getMaxFixedDataSize ( 0 ) ) { byte [ ] newData = new byte [ fieldMap . getMaxFixedDataSize ( 0 ) + 8 ] ; System . arraycopy ( data , 0 , newData , 0 , data . length ) ; data = newData ; } metaData2 = taskFixed2Meta . getByteArrayValue ( offset . intValue ( ) ) ; byte [ ] data2 = taskFixed2Data . getByteArrayValue ( offset . intValue ( ) ) ; byte [ ] recurringData = taskVarData . getByteArray ( uniqueID , fieldMap . getVarDataKey ( TaskField . RECURRING_DATA ) ) ; Task temp = m_file . getTaskByID ( id ) ; if ( temp != null ) { if ( ! taskVarMeta . getUniqueIdentifierSet ( ) . contains ( uniqueID ) ) { continue ; } else if ( temp . getName ( ) == null ) { m_file . removeTask ( temp ) ; } } task = m_file . addTask ( ) ; task . disableEvents ( ) ; fieldMap . populateContainer ( TaskField . class , task , uniqueID , new byte [ ] [ ] { data , data2 } , taskVarData ) ; enterpriseCustomFieldMap . populateContainer ( TaskField . class , task , uniqueID , null , taskVarData ) ; task . enableEvents ( ) ; task . setEstimated ( getDurationEstimated ( MPPUtility . getShort ( data , fieldMap . getFixedDataOffset ( TaskField . ACTUAL_DURATION_UNITS ) ) ) ) ; Integer externalTaskID = task . getSubprojectTaskID ( ) ; if ( externalTaskID != null && externalTaskID . intValue ( ) != 0 ) { task . setExternalTask ( true ) ; externalTasks . add ( task ) ; } processHyperlinkData ( task , taskVarData . getByteArray ( uniqueID , fieldMap . getVarDataKey ( TaskField . HYPERLINK_DATA ) ) ) ; task . setID ( id ) ; task . setOutlineCode ( 1 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE1_INDEX ) ) ) ; task . setOutlineCode ( 2 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE2_INDEX ) ) ) ; task . setOutlineCode ( 3 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE3_INDEX ) ) ) ; task . setOutlineCode ( 4 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE4_INDEX ) ) ) ; task . setOutlineCode ( 5 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE5_INDEX ) ) ) ; task . setOutlineCode ( 6 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE6_INDEX ) ) ) ; task . setOutlineCode ( 7 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE7_INDEX ) ) ) ; task . setOutlineCode ( 8 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE8_INDEX ) ) ) ; task . setOutlineCode ( 9 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE9_INDEX ) ) ) ; task . setOutlineCode ( 10 , getCustomFieldOutlineCodeValue ( taskVarData , m_outlineCodeVarData , uniqueID , fieldMap . getVarDataKey ( TaskField . OUTLINE_CODE10_INDEX ) ) ) ; task . setRecurring ( MPPUtility . getShort ( data , 40 ) == 2 ) ; task . setUniqueID ( uniqueID ) ; task . setExpanded ( ( ( metaData [ 12 ] & 0x02 ) == 0 ) ) ; readBitFields ( metaDataBitFlags , task , metaData ) ; readBitFields ( metaData2BitFlags , task , metaData2 ) ; m_parentTasks . put ( task . getUniqueID ( ) , ( Integer ) task . getCachedValue ( TaskField . PARENT_TASK_UNIQUE_ID ) ) ; if ( task . getStart ( ) == null || ( task . getCachedValue ( TaskField . SCHEDULED_START ) != null && task . getTaskMode ( ) == TaskMode . AUTO_SCHEDULED ) ) { task . setStart ( ( Date ) task . getCachedValue ( TaskField . SCHEDULED_START ) ) ; } if ( task . getFinish ( ) == null || ( task . getCachedValue ( TaskField . SCHEDULED_FINISH ) != null && task . getTaskMode ( ) == TaskMode . AUTO_SCHEDULED ) ) { task . setFinish ( ( Date ) task . getCachedValue ( TaskField . SCHEDULED_FINISH ) ) ; } if ( task . getDuration ( ) == null || ( task . getCachedValue ( TaskField . SCHEDULED_DURATION ) != null && task . getTaskMode ( ) == TaskMode . AUTO_SCHEDULED ) ) { task . setDuration ( ( Duration ) task . getCachedValue ( TaskField . SCHEDULED_DURATION ) ) ; } switch ( task . getConstraintType ( ) ) { case AS_LATE_AS_POSSIBLE : { if ( DateHelper . compare ( task . getStart ( ) , task . getLateStart ( ) ) < 0 ) { task . setStart ( task . getLateStart ( ) ) ; } if ( DateHelper . compare ( task . getFinish ( ) , task . getLateFinish ( ) ) < 0 ) { task . setFinish ( task . getLateFinish ( ) ) ; } break ; } case START_NO_LATER_THAN : case FINISH_NO_LATER_THAN : { if ( DateHelper . compare ( task . getFinish ( ) , task . getStart ( ) ) < 0 ) { task . setFinish ( task . getLateFinish ( ) ) ; } break ; } default : { break ; } } if ( recurringData != null ) { if ( recurringTaskReader == null ) { recurringTaskReader = new RecurringTaskReader ( m_file . getProjectProperties ( ) ) ; } recurringTaskReader . processRecurringTask ( task , recurringData ) ; task . setRecurring ( true ) ; } notes = task . getNotes ( ) ; if ( m_reader . getPreserveNoteFormatting ( ) == false ) { notes = RtfHelper . strip ( notes ) ; } task . setNotes ( notes ) ; Integer calendarID = ( Integer ) task . getCachedValue ( TaskField . CALENDAR_UNIQUE_ID ) ; if ( calendarID != null && calendarID . intValue ( ) != - 1 ) { ProjectCalendar calendar = m_file . getCalendarByUniqueID ( calendarID ) ; if ( calendar != null ) { task . setCalendar ( calendar ) ; } } SubProject sp = m_taskSubProjects . get ( task . getUniqueID ( ) ) ; task . setSubProject ( sp ) ; if ( sp != null ) { task . setExternalTask ( sp . isExternalTask ( task . getUniqueID ( ) ) ) ; if ( task . getExternalTask ( ) ) { task . setExternalTaskProject ( sp . getFullPath ( ) ) ; } } if ( task . getWBS ( ) != null ) { autoWBS = false ; } if ( ( metaData [ 9 ] & 0x80 ) == 0 ) { task . setSplits ( new LinkedList < DateRange > ( ) ) ; } if ( task . getTaskMode ( ) != TaskMode . MANUALLY_SCHEDULED ) { task . setManualDuration ( null ) ; } processTaskEnterpriseColumns ( uniqueID , task , taskVarData , metaData2 ) ; if ( task . getName ( ) == null && ( ( task . getStart ( ) == null || task . getStart ( ) . getTime ( ) == MPPUtility . getEpochDate ( ) . getTime ( ) ) || ( task . getFinish ( ) == null || task . getFinish ( ) . getTime ( ) == MPPUtility . getEpochDate ( ) . getTime ( ) ) || ( task . getCreateDate ( ) == null || task . getCreateDate ( ) . getTime ( ) == MPPUtility . getEpochDate ( ) . getTime ( ) ) ) ) { m_file . removeTask ( task ) ; task = m_file . addTask ( ) ; task . setNull ( true ) ; task . setUniqueID ( uniqueID ) ; task . setID ( id ) ; m_nullTaskOrder . put ( task . getID ( ) , task . getUniqueID ( ) ) ; continue ; } if ( data2 == null || data2 . length < 24 ) { m_nullTaskOrder . put ( task . getID ( ) , task . getUniqueID ( ) ) ; } else { Long key = Long . valueOf ( MPPUtility . getLong ( data2 , 16 ) ) ; m_taskOrder . put ( key , task . getUniqueID ( ) ) ; } m_eventManager . fireTaskReadEvent ( task ) ; } m_file . getProjectConfig ( ) . setAutoWBS ( autoWBS ) ; if ( ! externalTasks . isEmpty ( ) ) { processExternalTasks ( externalTasks ) ; } }
This method extracts and collates task data. The code below
goes through the modifier methods of the Task class in alphabetical
order extracting the data from the MPP file. Where there is no
mapping (e.g. the field is calculated on the fly, or we can't
find it in the data) the line is commented out.

The missing boolean attributes are probably represented in the Props
section of the task data, which we have yet to decode.

@throws java.io.IOException