enyo.kind({
  name: "WebLetter.Token",
  kind: "enyo.Control",
  classes: "token",
  topToken: true,
  subToken: false,
  subtokens: [], // subtokens
  multiline: false,
  isOptional: false,
  isEnabled: true,
  saveable: false,
  published: {
    description: "",
    key: "",
    subkey: ""
  },
  events: {
    onNewToken: "",
    onDisableToken: ""
  },
  create: function(args) {
    this.subtokens = new Array();
    this.inherited(arguments);
    if (this.isOptional) {
      this.createComponent({
        name: "toggle",
        kind: "onyx.ToggleButton",
        onContent: "on",
        offContent: "off",
        onChange: "buttonToggle"
      });
      this.$.toggle.value = this.isEnabled;
      if (this.isEnabled) {
        this.enableToken();
      }
      else {
        this.disableToken();
      }
    }
    if (this.saveable) {
      this.createComponent({
        name: "saveButton",
        kind: "onyx.Button",
        content: "Save",
        ontap: "saveAllData"
      });
      this.createComponent({
        name: "loadButton",
        kind: "onyx.Button",
        content: "Load",
        ontap: "loadAllData"
      });
    }
    this.$.descr.setContent(this.getDescription() + ":");
    if (this.subToken) {
      this.setKey(this.owner.getKey() + this.getSubkey());
      this.owner.addSubToken(this);
    }
    this.doNewToken();
  },
  getInput: function() {
    return this.$.input.getValue();
  },
  setInput: function(value) {
    this.$.input.setValue(value);
  },
  buttonToggle: function(inSender, inEvent) {
    if (this.$.toggle.getValue()) {
      this.enableToken();
    }
    else {
      this.disableToken();
    }
  },
  saveAllData: function(inSender, inEvent) {
    this.saveData(inEvent);
    for (i in this.subtokens) {
      this.subtokens[i].saveAllData(inSender, inEvent);
    }
  },
  saveData: function(inEvent) {
    if (inEvent == "autosave") {
      enyo.log("autosaving");
      prefix = "autosave-";
    }
    else {
      prefix = "";
    }
    enyo.log("saving: " + prefix + this.key + "=" + this.getInput());
    LocalStorage.set(prefix + this.key, this.getInput());
  },
  loadAllData: function(inSender, inEvent) {
    this.loadData();
    for (i in this.subtokens) {
      this.subtokens[i].loadAllData();
    }
  },
  loadData: function() {
    this.setInput(LocalStorage.get(this.key));
  },
  enableToken: function() {
    this.isEnabled = true;
    if (this.isOptional) {
      this.$.toggle.setValue(true);
    }
    this.enableInputs();
    for (i in this.subtokens) {
     this.subtokens[i].enableToken();
    }
  },
  disableToken: function() {
    this.isEnabled = false;
    if (this.isOptional) {
      this.$.toggle.setValue(false);
    }
    this.disableInputs();
    for (i in this.subtokens) {
     this.subtokens[i].disableToken();
    }
  },
  enableInputs: function() {
    if (this.$.input) {
      this.$.input.setDisabled(false);
    }
  },
  disableInputs: function() {
    if (this.$.input) {
      this.$.input.setDisabled(true);
    }
  },
  addSubToken: function(token) {
    enyo.log(this.name + ": add token " + token.name);
    this.subtokens.push(token);
  }
});

@@ -1324,32 +1324,64 @@
 en(this);%0A    %7D%0A
+    this.loadData(%22autosave-%22);%0A
     this.doNewTo
@@ -1383,24 +1383,24 @@
 NewToken();%0A
-
   %7D,%0A  getIn
@@ -1484,24 +1484,50 @@
 on(value) %7B%0A
+    if (this.$.input) %7B%0A  
     this.$.i
@@ -1548,16 +1548,109 @@
 value);%0A
+    %7D%0A    else %7B%0A      enyo.log(%22component %22 + this.name + %22 has no component input%22);%0A    %7D%0A
   %7D,%0A  b
@@ -2440,36 +2440,133 @@
 dData: function(
+prefix
 ) %7B%0A
+    if (!prefix) %7B%0A      prefix = %22%22;%0A    %7D%0A    enyo.log(%22loading: %22 + prefix + this.key);%0A
     this.setInpu
@@ -2584,16 +2584,25 @@
 age.get(
+prefix + 
 this.key

load autosave data at startup