@SuppressWarnings("unchecked")
  public Map<String, byte[]> encode(Object element) {

    if (element == null) {
      logger.error("The argument is null");
      throw new IllegalArgumentException("The argument is null");
    }

    logger.debug("Encoding: " + element.toString());

    PropertyDescriptor pd = null;
    Object fieldValue = null;
    Coder fieldCoder = null;

    try {
      for (Field f : fields)
        if (f.isAnnotationPresent(Attribute.class)) {
          pd = new PropertyDescriptor(f.getName(), element.getClass());
          fieldValue = pd.getReadMethod().invoke(element);
          if (fieldValue != null) {
            fieldCoder = mapFieldCoder.get(f.getAnnotation(Attribute.class).name());
            logger.trace(
                element.getClass().getName()
                    + " Update [ Field "
                    + f.getName()
                    + ", value: "
                    + fieldValue
                    + " ]");
            encoderMap.put(f.getAnnotation(Attribute.class).name(), fieldCoder.encode(fieldValue));
          } else {
            logger.error("The field ' " + f.getName() + " ' is null");
            throw new NullPointerException("The field ' " + f.getName() + " ' is null");
          }
        }
    } catch (IntrospectionException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException e) {
      logger.error("Error in retreving the value of the fields");
      e.printStackTrace();
    }

    return encoderMap;
  }
  @SuppressWarnings("unchecked")
  public void decode(
      Object element,
      Map<String, AttributeHandle> mapFieldNameAttributeHandle,
      AttributeHandleValueMap arg1) {

    if (element == null || arg1 == null || mapFieldNameAttributeHandle == null) {
      logger.error("Some arguments are null");
      throw new IllegalArgumentException("Some arguments are null");
    }

    PropertyDescriptor pd = null;
    Coder<Object> fieldCoder = null;
    byte[] currValue = null;
    try {
      for (Field f : fields)
        if (f.isAnnotationPresent(Attribute.class)) {
          pd = new PropertyDescriptor(f.getName(), element.getClass());
          fieldCoder = this.mapFieldCoder.get(f.getAnnotation(Attribute.class).name());
          currValue =
              arg1.get(mapFieldNameAttributeHandle.get(f.getAnnotation(Attribute.class).name()));
          pd.getWriteMethod().invoke(element, fieldCoder.decode(currValue));
          logger.debug(
              "Attribute decoded [ Field "
                  + f.getName()
                  + ", value: "
                  + fieldCoder.decode(currValue)
                  + " ]");
        }
    } catch (IntrospectionException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException
        | DecoderException e) {
      e.printStackTrace();
    }
  }