Index: language/data/demoData.json
===================================================================
--- language/data/demoData.json	(revision 0)
+++ language/data/demoData.json	(revision 0)
@@ -0,0 +1,12 @@
+{
+   "_id": "mccord",
+   "_rev": "1-b7cf5fa17688439515f77a9c14b2275f",
+   "type": "fluid.engage.docs.museum",
+   "name": "McCord Museum",
+   "languages": [
+       "en",
+       "fr"
+   ],
+   "lat": 43.662424,
+   "long": -79.441134
+}
\ No newline at end of file
Index: language/html/language.html
===================================================================
--- language/html/language.html	(revision 0)
+++ language/html/language.html	(revision 0)
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">    
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />        
+        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Language selection</title>
+        
+		<link rel="stylesheet" href="../../../../framework/fss/css/fss-mobile-layout.css" />
+        <link rel="stylesheet" href="../../../../framework/fss/css/fss-mobile-theme-iphone.css" />
+		<link rel="stylesheet" href="../../../../fluid-infusion/src/webapp/framework/fss/css/fss-layout.css" />
+        <link rel="stylesheet" href="../../../../fluid-infusion/src/webapp/framework/fss/css/fss-text.css" />
+        <link rel="stylesheet" href="../../../../fluid-infusion/src/webapp/framework/fss/css/fss-transitions.css" />
+		
+        <script src="../../../../fluid-infusion/src/webapp/lib/jquery/core/js/jquery.js"></script>
+		<script src="../../../../fluid-infusion/src/webapp/framework/core/js/Fluid.js"></script>
+        <script src="../../../../fluid-infusion/src/webapp/framework/core/js/FluidDOMUtilities.js"></script>
+        <script src="../../../../fluid-infusion/src/webapp/framework/core/js/DataBinding.js"></script>
+		<script src="../../../../lib/jquery/plugins/cookie/js/jquery.cookie.js"></script>
+		<script src="../../../../fluid-engage-core/framework/js/engageClientUtils.js"></script>
+		<script src="../../user/js/user.js"></script>
+        <script src="../js/language.js"></script>
+		        
+    </head>
+    <body class="fl-theme-iphone">
+        <div class="language">
+		    <div class="fl-navbar fl-table">
+                <div class="fl-table-row">
+                    <h1 class="fl-table-cell artifact-name">Language selection</h1>         
+                </div>
+            </div>
+            <ul class="fl-list-menu"></ul>
+		</div>
+        <script type="text/javascript">
+			fluid.language(".language");
+        </script>
+    </body>
+</html>
\ No newline at end of file
Index: language/js/language.js
===================================================================
--- language/js/language.js	(revision 0)
+++ language/js/language.js	(revision 0)
@@ -0,0 +1,142 @@
+﻿/*
+Copyright 2009 University of Toronto
+
+Licensed under the Educational Community License (ECL), Version 2.0 or the New
+BSD license. You may not use this file except in compliance with one these
+Licenses.
+
+You may obtain a copy of the ECL 2.0 License and BSD License at
+https://source.fluidproject.org/svn/LICENSE.txt
+*/
+
+/*global jQuery, fluid*/
+
+(function ($, fluid) {
+
+   /**
+    * Available languages: ids & labels.
+    */
+    var availableLanguages = {
+        en : 'English',
+        fr : 'Français'
+	};
+
+   /**
+    * Get language id.
+    * 
+    * @param {String} label, the language label.
+    * @return {String} id, the language id.
+    */
+    var getId = function (label) {
+		var id;
+        $.each(availableLanguages, function (key, value) {
+            if (label === value) {
+				id = key;
+				return false;
+            }
+        });
+		return id;
+    };
+		
+	/**
+	 * Set default language according to museum configuration
+	 * if user language hasn't been stored yet.
+	 * 
+	 * @param {Object} that, the component itself.
+	 * @param {String} id, the default language id.
+	 */
+	var setDefaultLanguage = function (that, id) {
+		if (fluid.engage.getCookie(that.options.cookieName) === null) {
+			fluid.engage.setCookie(that.options.cookieName, id);
+		}		
+	};
+	
+	/**
+	 * Get language label.
+	 * 
+	 * @param {String} id, the language id.
+	 * @return (String) the language label.
+	 */
+	var getLabel = function (id) {
+		if (availableLanguages[id]) {
+			return availableLanguages[id];
+		}
+	};
+	
+	/**
+	 * Callback function for retrieval of language options
+	 * according to museum configuration.
+	 * 
+	 * @param {Object} that, the component itself.
+	 */
+	var setLanguagesCallback = function (that) {
+		return {
+            success: function (data) {
+				var markup;
+				
+				// set default language
+				setDefaultLanguage(that, data.languages[0]);
+				
+				// set language options
+				$.each(data.languages, function (count, lang) {
+					markup = '<li><a class="flc-languageSelection-links" href="#">' + getLabel(lang) + '</a></li>';					
+					$(".fl-list-menu").append(markup);
+				});
+            }
+        };
+	};
+	
+	/**
+	 * Set languages according to museum configuration.
+	 * 
+	 * @param {Object} that, the component itself.
+	 */
+	var setLanguages = function (that) {
+		$.ajax({
+            url: that.options.dataUrl,
+            success: setLanguagesCallback(that).success,
+            dataType: "json",
+            async: true
+        });
+	};
+
+    /**
+     * Set user language.
+     * 
+     * @param {Object} that, the component itself.
+     * @param {Object} label, the language label.
+     */
+    var setUserLanguage = function (that, label) {
+		var id = getId(label);
+		fluid.engage.setCookie(that.options.cookieName, id);
+	};
+	
+	/**
+     * Initialize language selection.
+     * 
+     * @param {Object} container, the components container.
+     * @param {Object} options, the language options.
+     */
+    fluid.language = function (container, options) {
+		var that = fluid.initView("fluid.language", container, options);
+
+        $(".flc-languageSelection-links").live("click", function () {
+			setUserLanguage(that, $(this).text());
+        });
+		
+		// set language options & default language
+		setLanguages(that);
+
+        // initialize user component
+        that.user = fluid.initSubcomponent(that, "user");
+        that.uuid = that.user.getUuid();
+	};
+	
+    fluid.defaults("fluid.language", {
+        user: {
+            type: "fluid.user"
+        },
+		cookieName: "language",
+		dataUrl: "../data/demoData.json"
+	});
+})(jQuery, fluid);
\ No newline at end of file
Index: user/js/user.js
===================================================================
--- user/js/user.js	(revision 0)
+++ user/js/user.js	(revision 0)
@@ -0,0 +1,77 @@
+/*
+ Copyright 2009 University of Toronto
+
+ Licensed under the Educational Community License (ECL), Version 2.0 or the New
+ BSD license. You may not use this file except in compliance with one these
+ Licenses.
+
+ You may obtain a copy of the ECL 2.0 License and BSD License at
+ https://source.fluidproject.org/svn/LICENSE.txt
+
+ */
+
+/*global jQuery, fluid*/
+
+fluid = fluid || {};
+
+(function ($) {
+
+    /**
+     * Creates a URL for the user server side service.
+     */
+    var compileUrl = function () {
+        var url = "http://" + location.host + "/users/userService.js";
+        
+        return url;
+    };
+
+    /**
+     * Creates an empty object to use in the creator function and attaches two functions to it - 
+     * for UUID generation and retrieval. 
+     */
+    var setup = function () {
+        var that = {};
+        
+        that.generateUuid = function () {
+            var uuid;
+            
+            var successCallback = function (returnedData) {
+                uuid = returnedData;
+            };
+            
+            var errorCallback = function (XMLHttpRequest, textStatus, errorThrown) {
+                fluid.log("Status: " + textStatus);
+                fluid.log("Error: " + errorThrown);
+            };
+            
+            $.ajax({url: compileUrl(), async: false, success: successCallback, error: errorCallback});
+            
+            fluid.engage.setCookie(that.options.cookieName, uuid, {path: "/"});
+            
+            return uuid;
+        };
+        
+        that.getUuid = function () {
+            return fluid.engage.getCookie(that.options.cookieName, {path: "/"});
+        };
+        
+        return that;
+    };
+    
+    /**
+     * The component's creator function 
+     * 
+     * @param {Object} container, the container which will hold the component
+     * @param {Object} options, options passed into the component
+     */
+    fluid.user = function (container, options) {
+        var that = setup();
+        fluid.mergeComponentOptions(that, "fluid.user");
+        
+        return that;
+    };
+    
+    fluid.defaults("fluid.user", {
+        cookieName: "engage.uuid"
+    });    
+})(jQuery);
