/* (non-Javadoc)
   * @see uk.ac.ucl.excites.sapelli.collector.db.ProjectStore#deserialise(java.io.InputStream)
   */
  @Override
  public Project deserialise(InputStream in) throws IOException {
    // Deserialise valueSet:
    BitInputStream bitsIn = new BitWrapInputStream(in);
    ValueSet<ColumnSet> serialisedProjectVS = new ValueSet<ColumnSet>(PROJECT_SERIALISIATION_CS);
    serialisedProjectVS.readFromBitStream(bitsIn, true);
    bitsIn.close();

    // Retrieve FSI records:
    List<byte[]> fsiRecordBytesList =
        PROJECT_SERIALISIATION_FSI_RECORDS_COLUMN.retrieveValue(serialisedProjectVS);
    final List<Record> fsiRecords = new ArrayList<Record>(fsiRecordBytesList.size());
    for (byte[] fsiRecordBytes : fsiRecordBytesList)
      fsiRecords.add(FSI_SCHEMA.createRecord(fsiRecordBytes, true));

    // Retrieve & parse Project XML:
    return ProjectLoader.ParseProjectXML(
        new ByteArrayInputStream(
            PROJECT_SERIALISIATION_XML_COLUMN.retrieveValue(serialisedProjectVS)),
        new FormSchemaInfoProvider() {
          @Override
          public List<String> getByPassableFieldIDs(Form form) {
            for (Record fsiRecord : fsiRecords)
              if (FSI_FORM_POSITION_COLUMN.retrieveValue(fsiRecord).shortValue()
                  == form.getPosition())
                return ProjectRecordStore.this.getByPassableFieldIDs(fsiRecord);
            return null;
          }
        });
  }
  /* (non-Javadoc)
   * @see uk.ac.ucl.excites.sapelli.collector.db.ProjectStore#serialise(uk.ac.ucl.excites.sapelli.collector.model.Project, java.io.OutputStream)
   */
  @Override
  public void serialise(Project project, OutputStream out) throws IOException {
    // Project XML bytes:
    InputStream projectXMLFileIn =
        new FileInputStream(ProjectLoader.GetProjectXMLFile(getProjectFolder(project)));
    ByteArrayOutputStream projectXMLBytesOut = new ByteArrayOutputStream();
    IOUtils.copy(projectXMLFileIn, projectXMLBytesOut);
    projectXMLFileIn.close();
    projectXMLBytesOut.close();

    // FSI record bytes for each Form:
    List<byte[]> fsiRecordBytesList = new ArrayList<>(project.getNumberOfForms());
    for (Form form : project.getForms()) {
      Record fsiRecord = retrieveFSIRecord(form); // we query the projectStore to save time...
      if (fsiRecord == null) // ... but we don't rely on it:
      fsiRecord = getFSIRecord(form); // may trigger optionality analysis
      fsiRecordBytesList.add(fsiRecord.toBytes(true));
    }

    // Create serialisedProject valueSet:
    ValueSet<ColumnSet> serialisedProjectVS =
        new ValueSet<ColumnSet>(
            PROJECT_SERIALISIATION_CS, projectXMLBytesOut.toByteArray(), fsiRecordBytesList);

    // Return as byte array:
    BitOutputStream bitsOut = new BitWrapOutputStream(out);
    serialisedProjectVS.writeToBitStream(bitsOut, true);
    bitsOut.flush();
  }