For each attribute, define getter and setter on root DOM element of the widget
@param {Object} widget
@param {Array} attributes
@param {Function} callback
@param {Boolean} skipSetState: useful for handling setState in your component, rather than here
547933
function observeRoot(widget, attributes, callback, skipSetState) {
    attributes.forEach(attribute => {
        Object.defineProperty(widget.el, attribute, {
            get() {
                return widget.state[attribute];
            },
            set(value) {
                if (!skipSetState) {
                    widget.setState(attribute, value);
                }
                if (callback) {
                    callback(value);
                }
            }
        });
    });
}
410948
function(attrs) {
    for (var key in attrs) {
      //convert cls to class
      var mappedKey = key == 'cls' ? 'class' : key;
      
      this.attributes[mappedKey] = attrs[key];
    }
    return this;
  }
1222206
private void init(Context context, AttributeSet attrs){
        TypedArray attributeArray = context.obtainStyledAttributes(
                attrs,
                R.styleable.DiscreteSlider);

        try {
            tickMarkCount = attributeArray.getInteger(R.styleable.DiscreteSlider_tickMarkCount, 5);
            tickMarkRadius = attributeArray.getDimension(R.styleable.DiscreteSlider_tickMarkRadius, 8);
            position = attributeArray.getInteger(R.styleable.DiscreteSlider_position, 0);
            horizontalBarThickness = attributeArray.getDimension(R.styleable.DiscreteSlider_horizontalBarThickness, 4);
            backdropFillColor = attributeArray.getColor(R.styleable.DiscreteSlider_backdropFillColor, Color.GRAY);
            backdropStrokeColor = attributeArray.getColor(R.styleable.DiscreteSlider_backdropStrokeColor, Color.GRAY);
            backdropStrokeWidth = attributeArray.getDimension(R.styleable.DiscreteSlider_backdropStrokeWidth, 1);
            thumb = attributeArray.getDrawable(R.styleable.DiscreteSlider_thumb);
            progressDrawable = attributeArray.getDrawable(R.styleable.DiscreteSlider_progressDrawable);
        } finally {
            attributeArray.recycle();
        }

        View view = inflate(context, R.layout.discrete_slider, this);
        discreteSliderBackdrop = (DiscreteSliderBackdrop)view.findViewById(R.id.discrete_slider_backdrop);
        discreteSeekBar = (DiscreteSeekBar)view.findViewById(R.id.discrete_seek_bar);

        setTickMarkCount(tickMarkCount);
        setTickMarkRadius(tickMarkRadius);
        setHorizontalBarThickness(horizontalBarThickness);
        setBackdropFillColor(backdropFillColor);
        setBackdropStrokeColor(backdropStrokeColor);
        setBackdropStrokeWidth(backdropStrokeWidth);
        setPosition(position);
        setThumb(thumb);
        setProgressDrawable(progressDrawable);

        discreteSeekBar.setPadding(discreteSeekBarLeftPadding,0,discreteSeekBarRightPadding,0);

        discreteSeekBar.setOnDiscreteSeekBarChangeListener(new DiscreteSeekBar.OnDiscreteSeekBarChangeListener() {
            @Override
            public void onPositionChanged(int position) {
                if(onDiscreteSliderChangeListener != null){
                    onDiscreteSliderChangeListener.onPositionChanged(position);
                    setPosition(position);
                }
            }
        });
    }
471529
public void setFor(final IsWidget target) {
    if (init) {
      return;
    }
    init = true;
    //

    final InputElement input = getInputElement(target.asWidget());
    if (input != null) {
      if (!input.hasAttribute("id")) {
        input.setId(DOM.createUniqueId());
      }
      getElement().setAttribute("for", input.getId());
    }
  }
332329
function normalizeComponentAttributes(component, isAngleBracket, attrs) {
    var normalized = {};
    var attributeBindings = component.attributeBindings;
    var streamBasePath = component.isComponent ? '' : 'view.';
    var i, l;

    if (attrs.id && _emberHtmlbarsHooksGetValue.default(attrs.id)) {
      // Do not allow binding to the `id`
      normalized.id = _emberHtmlbarsHooksGetValue.default(attrs.id);
      component.elementId = normalized.id;
    } else {
      normalized.id = component.elementId;
    }

    if (attributeBindings) {
      for (i = 0, l = attributeBindings.length; i < l; i++) {
        var attr = attributeBindings[i];
        var colonIndex = attr.indexOf(':');

        var attrName, expression;
        if (colonIndex !== -1) {
          var attrProperty = attr.substring(0, colonIndex);
          attrName = attr.substring(colonIndex + 1);
          expression = ['get', '' + streamBasePath + attrProperty];
        } else if (attrs[attr]) {
          // TODO: For compatibility with 1.x, we probably need to `set`
          // the component's attribute here if it is a CP, but we also
          // probably want to suspend observers and allow the
          // willUpdateAttrs logic to trigger observers at the correct time.
          attrName = attr;
          expression = ['value', attrs[attr]];
        } else {
          attrName = attr;
          expression = ['get', '' + streamBasePath + attr];
        }

        _emberMetalDebug.assert('You cannot use class as an attributeBinding, use classNameBindings instead.', attrName !== 'class');

        normalized[attrName] = expression;
      }
    }

    if (isAngleBracket) {
      for (var prop in attrs) {
        var val = attrs[prop];
        if (!val) {
          continue;
        }

        if (typeof val === 'string' || val.isConcat) {
          normalized[prop] = ['value', val];
        }
      }
    }

    if (attrs.tagName) {
      component.tagName = attrs.tagName;
    }

    var normalizedClass = normalizeClass(component, attrs, streamBasePath);

    if (normalizedClass) {
      normalized.class = normalizedClass;
    }

    if (_emberMetalProperty_get.get(component, 'isVisible') === false) {
      var hiddenStyle = ['subexpr', '-html-safe', ['display: none;'], []];
      var existingStyle = normalized.style;

      if (existingStyle) {
        normalized.style = ['subexpr', 'concat', [existingStyle, ' ', hiddenStyle], []];
      } else {
        normalized.style = hiddenStyle;
      }
    }

    return normalized;
  }
1105435
function() {
      if (!this.el) {
        var attrs = Parse._getValue(this, 'attributes') || {};
        if (this.id) {
          attrs.id = this.id;
        }
        if (this.className) {
          attrs['class'] = this.className;
        }
        this.setElement(this.make(this.tagName, attrs), false);
      } else {
        this.setElement(this.el, false);
      }
    }
571352
function (attrs) {
		attrs = attrs || {};
		_.forEach(attrs, function (val, name) {
			this.setValue(name, val);
		}, this);
	}
1268725
function(el,prop,val,ret,args,action)
            {
              var e = new _changeEvent(el,prop,val,ret,args,action,'update');
              
              if(el.__kb !== undefined)
              {
                var localAttrListeners = el.__kb._attrUpdateListeners,
                    localStyleListeners = el.__kb._styleUpdateListeners,
                    localParentAttrListeners = el.__kb._parentAttrUpdateListeners,
                    localParentStyleListeners = el.__kb._parentStyleUpdateListeners;
              
                if(localAttrListeners[prop] !== undefined)
                {
                  loopListener(localAttrListeners[prop],e);
                }

                if(e._stopPropogation === undefined && localStyleListeners[prop] !== undefined)
                {
                  loopListener(localStyleListeners[prop],e);
                }
                
                if(e._stopPropogation === undefined && localAttrListeners[_all] !== undefined)
                {
                  loopListener(localAttrListeners[_all],e);
                  if(e._stopPropogation === undefined)
                  {
                    loopListener(localStyleListeners[_all],e);
                  }
                }
                
                if(e._stopPropogation === undefined && localParentAttrListeners[prop] !== undefined)
                {
                  loopParentListener(localParentAttrListeners[prop],e);
                }

                if(e._stopPropogation === undefined && localParentStyleListeners[prop] !== undefined)
                {
                  loopParentListener(localParentStyleListeners[prop],e);
                }
                
                if(e._stopPropogation === undefined && localParentAttrListeners[_all] !== undefined)
                {
                  loopParentListener(localParentAttrListeners[_all],e);

                  if(e._stopPropogation === undefined)
                  {
                    loopParentListener(localParentStyleListeners[_all],e);
                  }
                }
              
              }
              
              if(e._stopPropogation === undefined && _attrUpdateListeners[prop] !== undefined)
              {
                loopListener(_attrUpdateListeners[prop],e);
              }

              if(e._stopPropogation === undefined && _styleUpdateListeners[prop] !== undefined)
              {
                loopListener(_styleUpdateListeners[prop],e);
              }
              
              if(e._stopPropogation === undefined && _attrUpdateListeners[_all] !== undefined)
              {
                loopListener(_attrUpdateListeners[_all],e);
                if(e._stopPropogation === undefined)
                {
                  loopListener(_styleUpdateListeners[_all],e);
                }
              }

              if(e._preventDefault !== undefined) return false;

              return true;
            }
1081674
function (isDefault) {
    var attrValue = isDefault ? this.data : this.attrValue;
    if (attrValue === null || attrValue === undefined) { return; }
    window.HTMLElement.prototype.setAttribute.call(this.el, this.attrName,
                                                   this.stringify(attrValue));
  }
274970
function(attrs, options) {
        var attr, key, val, eve;
        if (attrs === null) return this;

        if (attrs.eClass) {
            attrs = attrs.get('name');
        }

        // Handle attrs is a hash or attrs is
        // property and options the value to be set.
        if (!_.isObject(attrs)) {
            key = attrs;
            (attrs = {})[key] = options;
        }

        var eResource = this.eResource();

        for (attr in attrs) {
            val = attrs[attr];
            if (typeof val !== 'undefined' && this.has(attr)) {
                if (this.isSet(attr)) {
                    this.unset(attr);
                }

                var feature = getEStructuralFeature(this.eClass, attr),
                    isContainment = feature.get('containment');

                var settingContainmentAttribute = (attr === 'containment') && (typeof(val) === 'string') && (this.eClass.values.name === 'EReference');
                if (settingContainmentAttribute) {
                    // Convert string 'true' to boolean true
                    val = (val.toLowerCase() === 'true');
                }

                this.values[attr] = val;

                if (isContainment) {
                  val.eContainingFeature = feature;
                  val.eContainer = this;
                }
                eve = 'change:' + attr;
                this.trigger('change ' + eve, attr);
                if (eResource) eResource.trigger('change', this);
            }
        }

        return this;
    }
307696
function () {
            var bind = this._bindingListeners.visible;
            if (bind) {
                var newValue = this._transform(bind.transform, false, "fromWidget");
                ariaUtilsJson.setValue(bind.inside, bind.to, newValue, bind.cb);
            }
        }
448784
function liveAttrsUpdate(newVal) {
		var newAttrs = live.getAttributeParts(newVal),
			name;
		for (name in newAttrs) {
			var newValue = newAttrs[name],
				// `oldAttrs` was set on the last run of setAttrs in this context
				//  (for this element and compute)
				oldValue = oldAttrs[name];
			// Only fire a callback
			//  if the value of the attribute has changed
			if (newValue !== oldValue) {
				// set on DOM attributes (dispatches an "attributes" event as well)
				domMutateNode.setAttribute.call(el, name, newValue);
				// get registered callback for attribute name and fire
				var callback = viewCallbacks.attr(name);
				if (callback) {
					callback(el, {
						attributeName: name,
						scope: scope,
						options: options
					});
				}
			}
			// remove key found in new attrs from old attrs
			delete oldAttrs[name];
		}
		// any attrs left at this point are not set on the element now,
		// so remove them.
		for (name in oldAttrs) {
			domMutateNode.removeAttribute.call(el, name);
		}
		oldAttrs = newAttrs;
	}
1308336
function(attr, options) {
      (options || (options = {})).unset = true;
      return this.set(attr, null, options);
    }
845892
def on_change(self, attr, *callbacks):
        ''' 

        '''
        if len(callbacks) == 0:
            raise ValueError("on_change takes an attribute name and one or more callbacks, got only one parameter")

        _callbacks = self._callbacks.setdefault(attr, [])
        for callback in callbacks:

            if callback in _callbacks:
                continue

            _check_callback(callback, ('attr', 'old', 'new'))

            _callbacks.append(callback)
762281
function( attr, val ) {
				var orgVal = this.getAttribute( attr );
				if ( val !== orgVal ) {
					!this._.attrChanges && ( this._.attrChanges = {} );

					// Saved the original attribute val.
					if ( !( attr in this._.attrChanges ) )
						this._.attrChanges[ attr ] = orgVal;

					this.setAttribute( attr, val );
				}
			}
1083762
@Override
    public BaseJsonBo setAttribute(String attrName, Object value, boolean triggerChange) {
        if (value instanceof JsonNode) {
            if (value instanceof NullNode || value instanceof MissingNode) {
                super.setAttribute(attrName, null, triggerChange);
            } else {
                super.setAttribute(attrName, value.toString(), triggerChange);
            }
        } else {
            JsonNode node = null;
            if (value instanceof String) {
                node = tryParseJson(value.toString());
            }
            node = node != null ? node : SerializationUtils.toJson(value);
            super.setAttribute(attrName, node.toString(), triggerChange);
        }
        return this;
    }
899223
function kwtoattr(html_attrs, merge){
      var k,v;
      var rv = '';
      if (merge) {
       for (k in merge) {
         if (merge.hasOwnProperty(k)) {
           v = merge[k];
           if(html_attrs.hasOwnProperty(k)){
              v = html_attrs[k] + ' ' + v
           }
           html_attrs[k] = v
         }
       }
     }

     var booleanAttributes = " hidden novalidate formnovalidate readonly required multiple autofocus disabled selected";

       for (k in html_attrs){
          if(!html_attrs.hasOwnProperty(k) || typeof html_attrs[k] !== 'string')
            continue;

          if (booleanAttributes.indexOf(" " + k + " ") > -1) {
            if (html_attrs[k]==k || html_attrs[k]=="") //otherwise omit
              rv += k + " ";
          } else {
           rv += k + '= "' + html_attrs[k].replace(/&/g,'&amp;').replace(/"/g,'&quot;') + '" ';
         }
       }
       return rv;
   }