text: var _ = require('lodash');
  var utils = require('./utils');
  
  // Create element and apply shcema
  function createElement(feed, schema, value) {
      if (schema.bool && !value) return;
  
      var el = feed.ele(schema.tag);
      if (!schema.bool) applySchema(el, schema, value);
  }
  
  // Apply an attribute-schema to an element
  function createAttr(el, schema, value) {
      schema = utils.defaultAttribute(schema || {});
  
      // Apply default value
      if (schema.default !== undefined) {
          value = _.isPlainObject(value)? _.defaults(value, schema.default || {}) : (value || schema.default);
      }
  
      if (value == null) return;
  
      // Transform value
      value = schema.transform(value);
  
      // Add attribute
      el.att(schema.name, value);
  }
  
  
  // Apply a schema to an existing element
  function applySchema(el, schema, value) {
      var innerValue;
      schema = utils.defaultSchema(schema || {});
  
      // Apply default value
      if (schema.default !== undefined) {
          value = _.isPlainObject(value)? _.defaults(value, schema.default || {}) : (value || schema.default);
      }
  
      if (value == null) {
          el.remove();
          return;
      }
  
      // Map value
      if (schema.map.to && utils.isBasicValue(value)) {
          value = _.fromPairs([[schema.map.to, value]]);
      }
  
      // Transform value
      value = schema.transform(value);
  
      innerValue = value;
  
      schema.value = value;
      var isText = _.result(schema, 'text', true);
      var isRaw = _.result(schema, 'raw', false);
      var isCDATA = _.result(schema, 'cdata', false);
  
      // Extract inner value
      if (schema.inner) innerValue = _.get(innerValue, schema.inner);
  
      // Add value if string or number
      if (isText && utils.isBasicValue(innerValue)) {
          if (isCDATA) el.dat(innerValue);
          else if (isRaw) el.raw(innerValue);
          else el.txt(innerValue);
      }
  
      // Apply attributes
      _.each(schema.attributes, function(attr, key) {
          var val = _.get(value, key);
          createAttr(el, _.defaults(attr, {
              name: key
          }), val);
      });
  
      // Apply sub-fields
      _.each(schema.fields, function(field, key) {
          // Extract value to use for the field
          var val = key == '$'? value : _.get(value, key);
  
          // Create new element and handle arrays
          if (_.isArray(val)) {
              _.each(val, _.partial(createElement, el, field));
          } else {
              createElement(el, _.defaults(field, {
                  tag: key
              }), val);
          }
      });
  }
  
  module.exports = {
      createElement: createElement,
      applySchema: applySchema
  };
  