code: private MBeanInfo buildMbeanInfo(JmxAttributeFieldInfo[] attributeFieldInfos,
  			JmxAttributeMethodInfo[] attributeMethodInfos, JmxOperationInfo[] operationInfos, boolean ignoreErrors) {
  
  		// NOTE: setup the maps that track previous class configuration
  		Map<String, JmxAttributeFieldInfo> attributeFieldInfoMap = null;
  		if (attributeFieldInfos != null) {
  			attributeFieldInfoMap = new HashMap<String, JmxAttributeFieldInfo>();
  			for (JmxAttributeFieldInfo info : attributeFieldInfos) {
  				attributeFieldInfoMap.put(info.getFieldName(), info);
  			}
  		}
  		Map<String, JmxAttributeMethodInfo> attributeMethodInfoMap = null;
  		if (attributeMethodInfos != null) {
  			attributeMethodInfoMap = new HashMap<String, JmxAttributeMethodInfo>();
  			for (JmxAttributeMethodInfo info : attributeMethodInfos) {
  				attributeMethodInfoMap.put(info.getMethodName(), info);
  			}
  		}
  		Map<String, JmxOperationInfo> attributeOperationInfoMap = null;
  		if (operationInfos != null) {
  			attributeOperationInfoMap = new HashMap<String, JmxOperationInfo>();
  			for (JmxOperationInfo info : operationInfos) {
  				attributeOperationInfoMap.put(info.getMethodName(), info);
  			}
  		}
  
  		Set<String> attributeNameSet = new HashSet<String>();
  		List<MBeanAttributeInfo> attributes = new ArrayList<MBeanAttributeInfo>();
  		// NOTE: methods override fields so subclasses can stop exposing of fields
  		discoverAttributeMethods(attributeMethodInfoMap, attributeNameSet, attributes, ignoreErrors);
  		discoverAttributeFields(attributeFieldInfoMap, attributeNameSet, attributes);
  		List<MBeanOperationInfo> operations = discoverOperations(attributeOperationInfoMap);
  
  		return new MBeanInfo(target.getClass().getName(), description,
  				attributes.toArray(new MBeanAttributeInfo[attributes.size()]), null,
  				operations.toArray(new MBeanOperationInfo[operations.size()]), null);
  	}
docs: Build our JMX information object by using reflection.