// function which fills all part of Heka message
func setHekaMessageFields(m plugin.MetricType, msg *message.Message) error {
	mName := make([]string, 0, len(m.Namespace()))
	var dimField *message.Field
	var err error
	// Loop on namespace elements
	for _, elt := range m.Namespace() {
		logger.WithField("_block", "setHekaMessageFields").Debug(
			fmt.Sprintf("Namespace %#+v",
				elt))
		// Dynamic element is not inserted in metric name
		// but rather added to dimension field
		if elt.IsDynamic() {
			dimField, err = addToDimensions(dimField, elt.Name)
			if err != nil {
				logger.WithField("_block", "setHekaMessageFields").Error(err)
				return err
			}
			addField(elt.Name, elt.Value, msg)
		} else {
			// Static element is concatenated to metric name
			mName = append(mName, elt.Value)
		}
	}
	// Processing of tags
	if len(m.Tags()) > 0 {
		for tag, value := range m.Tags() {
			logger.WithField("_block", "setHekaMessageFields").Debug(
				fmt.Sprintf("Adding tag=%s value=%s",
					tag, value))
			dimField, err = addToDimensions(dimField, tag)
			if err != nil {
				logger.WithField("_block", "setHekaMessageFields").Error(err)
				return err
			}
			addField(tag, value, msg)
		}
	}
	if dimField != nil {
		msg.AddField(dimField)
	}
	// Handle metric name
	metricName := strings.Join(mName, ".")
	// TODO protect access using mutex
	// for potential race conditions
	logger.WithField("_block", "setHekaMessageFields").Debug(
		fmt.Sprintf("Checking metric=%s",
			metricName))
	// Is mapping already stored
	if val, ok := MetricMappings[metricName]; ok {
		logger.WithField("_block", "setHekaMessageFields").Debug(
			fmt.Sprintf("Metric=%s in cache %s",
				metricName, val))
		metricName = val
	} else {
		oldMetricName := metricName
		logger.WithField("_block", "setHekaMessageFields").Debug(
			fmt.Sprintf("Metric=%s not in cache",
				metricName))
		// Namespace handling
		for kmapping, vmapping := range globalMappings.Namespace {
			logger.WithField("_block", "setHekaMessageFields").Debug(
				fmt.Sprintf("Checking metric=%s against namespace %s (%s)",
					metricName, kmapping, vmapping))
			// Try to see if substitution changes something
			newMetricName := strings.Replace(metricName, kmapping, vmapping, 1)
			if strings.Compare(newMetricName, metricName) != 0 {
				MetricMappings[oldMetricName] = newMetricName
				logger.WithField("_block", "setHekaMessageFields").Debug(
					fmt.Sprintf("Changing metric=%s into %s",
						metricName, newMetricName))
				metricName = newMetricName
			}
		}
		// Metrics handling
		for kmapping, vmapping := range globalMappings.Metrics {
			logger.WithField("_block", "setHekaMessageFields").Debug(
				fmt.Sprintf("Checking metric=%s against metric %s (%s)",
					metricName, kmapping, vmapping))
			// Try to see if substitution changes something
			newMetricName := strings.Replace(metricName, kmapping, vmapping, 1)
			if strings.Compare(newMetricName, metricName) != 0 {
				MetricMappings[oldMetricName] = newMetricName
				logger.WithField("_block", "setHekaMessageFields").Debug(
					fmt.Sprintf("Changing metric=%s into %s",
						metricName, newMetricName))
				metricName = newMetricName
			}
		}
	}
	addField("name", metricName, msg)
	addField("value", getData(m.Data()), msg)
	addField("timestamp", m.Timestamp().UnixNano(), msg)
	return nil
}