text: // Returns true if path is a valid field name (path),
  // i.e. a sequence of identifiers, separated by "."
  TiddlyWiki.isValidFieldName = function(name)
  {
  	var match = /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*/.exec(name);
  	return match && (match[0] == name);
  };
  
  // Throws an exception when name is not a valid field name.
  TiddlyWiki.checkFieldName = function(name)
  {
  	if(!TiddlyWiki.isValidFieldName(name))
  		throw config.messages.invalidFieldName.format([name]);
  };
  
  function StringFieldAccess(n,readOnly)
  {
  	this.set = readOnly ?
  			function(t,v) {if(v != t[n]) throw config.messages.fieldCannotBeChanged.format([n]);} :
  			function(t,v) {if(v != t[n]) {t[n] = v; return true;}};
  	this.get = function(t) {return t[n];};
  }
  
  function DateFieldAccess(n)
  {
  	this.set = function(t,v) {
  		var d = v instanceof Date ? v : Date.convertFromYYYYMMDDHHMM(v);
  		if(d != t[n]) {
  			t[n] = d; return true;
  		}
  	};
  	this.get = function(t) {return t[n].convertToYYYYMMDDHHMM();};
  }
  
  function LinksFieldAccess(n)
  {
  	this.set = function(t,v) {
  		var s = (typeof v == "string") ? v.readBracketedList() : v;
  		if(s.toString() != t[n].toString()) {
  			t[n] = s; return true;
  		}
  	};
  	this.get = function(t) {return String.encodeTiddlyLinkList(t[n]);};
  }
  
  TiddlyWiki.standardFieldAccess = {
  	// The set functions return true when setting the data has changed the value.
  	"title":    new StringFieldAccess("title",true),
  	// Handle the "tiddler" field name as the title
  	"tiddler":  new StringFieldAccess("title",true),
  	"text":     new StringFieldAccess("text"),
  	"modifier": new StringFieldAccess("modifier"),
  	"modified": new DateFieldAccess("modified"),
  	"creator":  new StringFieldAccess("creator"),
  	"created":  new DateFieldAccess("created"),
  	"tags":     new LinksFieldAccess("tags")
  };
  
  TiddlyWiki.isStandardField = function(name)
  {
  	return TiddlyWiki.standardFieldAccess[name] != undefined;
  };
  
  // Sets the value of the given field of the tiddler to the value.
  // Setting an ExtendedField's value to null or undefined removes the field.
  // Setting a namespace to undefined removes all fields of that namespace.
  // The fieldName is case-insensitive.
  // All values will be converted to a string value.
  TiddlyWiki.prototype.setValue = function(tiddler,fieldName,value)
  {
  	TiddlyWiki.checkFieldName(fieldName);
  	var t = this.resolveTiddler(tiddler);
  	if(!t)
  		return;
  	fieldName = fieldName.toLowerCase();
  	var isRemove = (value === undefined) || (value === null);
  	var accessor = TiddlyWiki.standardFieldAccess[fieldName];
  	if(accessor) {
  		if(isRemove)
  			// don't remove StandardFields
  			return;
  		var h = TiddlyWiki.standardFieldAccess[fieldName];
  		if(!h.set(t,value))
  			return;
  	} else {
  		var oldValue = t.fields[fieldName];
  		if(isRemove) {
  			if(oldValue !== undefined) {
  				// deletes a single field
  				delete t.fields[fieldName];
  			} else {
  				// no concrete value is defined for the fieldName
  				// so we guess this is a namespace path.
  				// delete all fields in a namespace
  				var re = new RegExp("^"+fieldName+"\\.");
  				var dirty = false;
  				var n;
  				for(n in t.fields) {
  					if(n.match(re)) {
  						delete t.fields[n];
  						dirty = true;
  					}
  				}
  				if(!dirty)
  					return;
  			}
  		} else {
  			// the "normal" set case. value is defined (not null/undefined)
  			// For convenience provide a nicer conversion Date->String
  			value = value instanceof Date ? value.convertToYYYYMMDDHHMMSSMMM() : String(value);
  			if(oldValue == value)
  				return;
  			t.fields[fieldName] = value;
  		}
  	}
  	// When we are here the tiddler/store really was changed.
  	this.notify(t.title,true);
  	if(!fieldName.match(/^temp\./))
  		this.setDirty(true);
  };
  
  // Returns the value of the given field of the tiddler.
  // The fieldName is case-insensitive.
  // Will only return String values (or undefined).
  TiddlyWiki.prototype.getValue = function(tiddler,fieldName)
  {
  	var t = this.resolveTiddler(tiddler);
  	if(!t)
  		return undefined;
  	if(fieldName.indexOf(config.textPrimitives.sectionSeparator) === 0 || fieldName.indexOf(config.textPrimitives.sliceSeparator) === 0) {
  		var sliceType = fieldName.substr(0, 2);
  		var sliceName = fieldName.substring(2);
  		return store.getTiddlerText("%0%1%2".format(t.title,sliceType,sliceName));
  	} else {
  		fieldName = fieldName.toLowerCase();
  		var accessor = TiddlyWiki.standardFieldAccess[fieldName];
  		if(accessor) {
  			return accessor.get(t);
  		}
  	}
  	return t.fields[fieldName];
  };
  
  // Calls the callback function for every field in the tiddler.
  // When callback function returns a non-false value the iteration stops
  // and that value is returned.
  // The order of the fields is not defined.
  // @param callback a function(tiddler,fieldName,value).
  TiddlyWiki.prototype.forEachField = function(tiddler,callback,onlyExtendedFields)
  {
  	var t = this.resolveTiddler(tiddler);
  	if(!t)
  		return undefined;
  	var n,result;
  	for(n in t.fields) {
  		result = callback(t,n,t.fields[n]);
  		if(result)
  			return result;
  		}
  	if(onlyExtendedFields)
  		return undefined;
  	for(n in TiddlyWiki.standardFieldAccess) {
  		if(n != "tiddler") {
  			// even though the "title" field can also be referenced through the name "tiddler"
  			// we only visit this field once.
  			result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
  			if(result)
  				return result;
  		}
  	}
  	return undefined;
  };
  
  