void
FieldInstructionGroup::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & messageBuilder) const
{
  bool present = true;

  if(! isMandatory())
  {
    present = pmap.checkNextField();
  }

  if(present)
  {
    if(!segmentBody_)
    {
      decoder.reportFatal("[ERR U08}", "Segment not defined for Group instruction.");
    }
    if(messageBuilder.getApplicationType() != segmentBody_->getApplicationType())
    {
//      std::cout << "Decoding group into new segment: " << segmentBody_->getApplicationType() << std::endl;
      Messages::ValueMessageBuilder & groupBuilder(
        messageBuilder.startGroup(
          identity_,
          segmentBody_->getApplicationType(),
          segmentBody_->getApplicationTypeNamespace(),
          segmentBody_->fieldCount()));

      decoder.decodeGroup(source, segmentBody_, groupBuilder);
      messageBuilder.endGroup(
        identity_,
        groupBuilder);
    }
    else
    {
//      std::cout << "Folding group into parent segment: " << segmentBody_->getApplicationType() << std::endl;
      // Because the application types match,
      // the group fields are decoded directly into to the current
      // field set.  As a result the group "disappears" completely
      // from the application message.  This is a good thing.  Groups
      // are an artifact of the template used to encode the message
      // rather than being an attribute of the actual message being
      // encoded.  In fact, the same message encoded with different
      // templates could be transmitted with different sets of fields
      // in groups.
      decoder.decodeGroup(source, segmentBody_, messageBuilder);
    }
  }
}
void
FieldInstructionSequence::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & builder) const
{
  if(!segment_)
  {
    decoder.reportFatal("[ERR U07]", "SegmentBody not defined for Sequence instruction.");
  }
  size_t length = 0;
  Codecs::FieldInstructionCPtr lengthInstruction;
  Messages::SingleValueBuilder<uint32> lengthSet;
  if(segment_->getLengthInstruction(lengthInstruction))
  {
    source.beginField(lengthInstruction->getIdentity()->name());
    lengthInstruction->decode(source, pmap, decoder, lengthSet);
  }
  else
  {
    FieldInstructionUInt32 defaultLengthInstruction;
    defaultLengthInstruction.setPresence(isMandatory());
    defaultLengthInstruction.decode(source, pmap, decoder, lengthSet);
  }
  if(lengthSet.isSet())
  {
    length = lengthSet.value();

    Messages::ValueMessageBuilder & sequenceBuilder = builder.startSequence(
      identity_,
      segment_->getApplicationType(),
      segment_->getApplicationTypeNamespace(),
      segment_->fieldCount(),
      lengthSet.identity(),
      length);

    for(size_t nEntry = 0; nEntry < length; ++nEntry)
    {
      if(decoder.getLogOut())
      {
        std::stringstream msg;
        msg << "Sequence entry #" << nEntry << " of " << length << std::ends;
        decoder.logMessage(msg.str());
      }

      Messages::ValueMessageBuilder & entrySet(
        sequenceBuilder.startSequenceEntry(
          segment_->getApplicationType(),
          segment_->getApplicationTypeNamespace(),
          segment_->fieldCount()));
      decoder.decodeGroup(source, segment_, entrySet);
      sequenceBuilder.endSequenceEntry(entrySet);
    }
    builder.endSequence(identity_, sequenceBuilder);
  }
}