public byte[] getBytes() throws HeaderException {
   try {
     int length =
         HEADER_LENGTH
             + (scopeInformationElements.size() * InformationElement.LENGTH)
             + (informationElements.size() * InformationElement.LENGTH);
     if (length % 4 != 0) {
       length += (length % 4); // padding
     }
     byte[] data = new byte[length];
     // template ID
     System.arraycopy(Shorts.toByteArray((short) getTemplateID()), 0, data, 0, 2);
     // field count
     System.arraycopy(Shorts.toByteArray((short) getFieldCount()), 0, data, 2, 2);
     // scope field count
     System.arraycopy(Shorts.toByteArray((short) getScopeFieldCount()), 0, data, 4, 2);
     // information elements
     int offset = HEADER_LENGTH;
     for (InformationElement ie : scopeInformationElements) {
       System.arraycopy(ie.getBytes(), 0, data, offset, InformationElement.LENGTH);
       offset += InformationElement.LENGTH;
     }
     for (InformationElement ie : informationElements) {
       System.arraycopy(ie.getBytes(), 0, data, offset, InformationElement.LENGTH);
       offset += InformationElement.LENGTH;
     }
     return data;
   } catch (Exception e) {
     throw new HeaderException("Error while generating the bytes: " + e.getMessage());
   }
 }
  public List<InformationElement> getElements(ElementId elementId) {
    ArrayList<InformationElement> ret = new ArrayList<InformationElement>();

    for (InformationElement element : elements)
      if (element.getElementId() == elementId) ret.add(element);

    return ret;
  }
 public static OptionTemplateRecord parse(byte[] data) throws HeaderException {
   try {
     if (data.length < HEADER_LENGTH) {
       throw new HeaderException("Data array too short.");
     }
     OptionTemplateRecord otr = new OptionTemplateRecord();
     // template ID
     byte[] templateID = new byte[2];
     System.arraycopy(data, 0, templateID, 0, 2);
     otr.setTemplateID(Ints.fromByteArray(templateID));
     // field count
     byte[] fieldCount = new byte[2];
     System.arraycopy(data, 2, fieldCount, 0, 2);
     otr.setFieldCount(Ints.fromByteArray(fieldCount));
     // scope field count
     byte[] scopeFieldCount = new byte[2];
     System.arraycopy(data, 4, scopeFieldCount, 0, 2);
     otr.setScopeFieldCount(Ints.fromByteArray(scopeFieldCount));
     int offset = HEADER_LENGTH;
     for (int i = 0; i < otr.getFieldCount(); i++) {
       byte[] subData = new byte[InformationElement.LENGTH];
       System.arraycopy(
           data, offset + (i * InformationElement.LENGTH), subData, 0, InformationElement.LENGTH);
       InformationElement ie = InformationElement.parse(subData);
       if (i < otr.getScopeFieldCount()) {
         otr.getScopeInformationElements().add(ie);
       } else {
         otr.getInformationElements().add(ie);
       }
     }
     return otr;
   } catch (Exception e) {
     throw new HeaderException("Parse error: " + e.getMessage());
   }
 }
  public void replaceElement(InformationElement element) {
    // Remove any elements with the same element ID
    for (int i = 0; i < elements.size(); i++)
      if (elements.get(i).getElementId() == element.getElementId()) {
        elements.remove(i);
        i--;
      }

    // Add the new created element
    elements.add(element);
  }
  public InformationElement getElement(ElementId elementId) {
    for (InformationElement element : elements)
      if (element.getElementId() == elementId) return element;

    return null;
  }