You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by ro...@apache.org on 2014/11/13 02:40:45 UTC

[2/6] incubator-usergrid git commit: Merged ported Apigee android sdk to 1.0

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/URLConnectionFactory.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/URLConnectionFactory.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/URLConnectionFactory.java
new file mode 100755
index 0000000..11e1f2d
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/URLConnectionFactory.java
@@ -0,0 +1,12 @@
+package org.apache.usergrid.android.sdk;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URLConnection;
+
+/**
+ * @y.exclude
+ */
+public interface URLConnectionFactory {
+	public URLConnection openConnection(String urlAsString) throws MalformedURLException, IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ApiResponseCallback.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ApiResponseCallback.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ApiResponseCallback.java
new file mode 100755
index 0000000..76846a1
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ApiResponseCallback.java
@@ -0,0 +1,12 @@
+package org.apache.usergrid.android.sdk.callbacks;
+
+import org.apache.usergrid.android.sdk.response.ApiResponse;
+
+/**
+ * Default callback for async requests that return an ApiResponse object
+ */
+public interface ApiResponseCallback extends ClientCallback<ApiResponse> {
+
+	public void onResponse(ApiResponse response);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientAsyncTask.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientAsyncTask.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientAsyncTask.java
new file mode 100755
index 0000000..7780f30
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientAsyncTask.java
@@ -0,0 +1,47 @@
+package org.apache.usergrid.android.sdk.callbacks;
+
+import android.os.AsyncTask;
+
+/**
+ * Default async request handler
+ */
+public abstract class ClientAsyncTask<T> extends AsyncTask<Void, Exception, T> {
+
+	ClientCallback<T> callback;
+
+	/**
+	 * Default constructor for starting an async request
+	 */
+	public ClientAsyncTask(ClientCallback<T> callback) {
+		this.callback = callback;
+	}
+
+	@Override
+	protected T doInBackground(Void... v) {
+		try {
+			return doTask();
+		} catch (Exception e) {
+			this.publishProgress(e);
+		}
+		return null;
+	}
+
+	/**
+	 * Starts the async request
+	 */
+	public abstract T doTask();
+
+	@Override
+	protected void onPostExecute(T response) {
+		if (callback != null) {
+			callback.onResponse(response);
+		}
+	}
+
+	@Override
+	protected void onProgressUpdate(Exception... e) {
+		if ((callback != null) && (e != null) && (e.length > 0)) {
+			callback.onException(e[0]);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientCallback.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientCallback.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientCallback.java
new file mode 100755
index 0000000..4dd27c4
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/ClientCallback.java
@@ -0,0 +1,12 @@
+package org.apache.usergrid.android.sdk.callbacks;
+
+/**
+ * Interface for all callback methods
+ */
+public interface ClientCallback<T> {
+
+	public void onResponse(T response);
+
+	public void onException(Exception e);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/GroupsRetrievedCallback.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/GroupsRetrievedCallback.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/GroupsRetrievedCallback.java
new file mode 100755
index 0000000..839535e
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/GroupsRetrievedCallback.java
@@ -0,0 +1,16 @@
+package org.apache.usergrid.android.sdk.callbacks;
+
+import java.util.Map;
+
+import org.apache.usergrid.android.sdk.entities.Group;
+
+/**
+ * Callback for GET requests on groups entities
+ * @see org.apache.usergrid.android.sdk.UGClient#getGroupsForUserAsync(String,GroupsRetrievedCallback)
+ */
+public interface GroupsRetrievedCallback extends
+		ClientCallback<Map<String, Group>> {
+
+	public void onGroupsRetrieved(Map<String, Group> groups);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/QueryResultsCallback.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/QueryResultsCallback.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/QueryResultsCallback.java
new file mode 100755
index 0000000..2d3df8d
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/callbacks/QueryResultsCallback.java
@@ -0,0 +1,14 @@
+package org.apache.usergrid.android.sdk.callbacks;
+
+import org.apache.usergrid.android.sdk.UGClient.Query;
+
+/**
+ * Callback for async requests using the Query interface
+ * @see org.apache.usergrid.android.sdk.UGClient.Query
+ * @see org.apache.usergrid.android.sdk.UGClient#queryActivityFeedForUserAsync(String, QueryResultsCallback)
+ */
+public interface QueryResultsCallback extends ClientCallback<Query> {
+
+	public void onQueryResults(Query query);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Activity.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Activity.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Activity.java
new file mode 100755
index 0000000..9e90a26
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Activity.java
@@ -0,0 +1,1019 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Ed Anuff and Usergrid, all rights reserved.
+ * http://www.usergrid.com
+ * 
+ * This file is part of Usergrid Core.
+ * 
+ * Usergrid Core is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ * 
+ * Usergrid Core is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * Usergrid Core. If not, see <http://www.gnu.org/licenses/>.
+ ******************************************************************************/
+package org.apache.usergrid.android.sdk.entities;
+
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+/**
+ * An entity type for representing posts to an activity stream. These are similar to
+ * the more generic message entity type except provide the necessary properties
+ * for supporting activity stream implementations.
+ * 
+ * @see <a href="http://activitystrea.ms/specs/json/1.0/">JSON activity stream spec</a>
+ * @see <a href="http://apigee.com/docs/app-services/content/activity">Activity entity documentation</a>
+ */
+public class Activity extends Entity {
+
+    public static final String ENTITY_TYPE = "activity";
+
+    public static final String PROP_ACTOR = "actor";
+
+    public static final String VERB_ADD = "add";
+    public static final String VERB_CANCEL = "cancel";
+    public static final String VERB_CHECKIN = "checkin";
+    public static final String VERB_DELETE = "delete";
+    public static final String VERB_FAVORITE = "favorite";
+    public static final String VERB_FOLLOW = "follow";
+    public static final String VERB_GIVE = "give";
+    public static final String VERB_IGNORE = "ignore";
+    public static final String VERB_INVITE = "invite";
+    public static final String VERB_JOIN = "join";
+    public static final String VERB_LEAVE = "leave";
+    public static final String VERB_LIKE = "like";
+    public static final String VERB_MAKE_FRIEND = "make-friend";
+    public static final String VERB_PLAY = "play";
+    public static final String VERB_POST = "post";
+    public static final String VERB_RECEIVE = "receive";
+    public static final String VERB_REMOVE = "remove";
+    public static final String VERB_REMOVE_FRIEND = "remove-friend";
+    public static final String VERB_REQUEST_FRIEND = "request-friend";
+    public static final String VERB_RSVP_MAYBE = "rsvp-maybe";
+    public static final String VERB_RSVP_NO = "rsvp-no";
+    public static final String VERB_RSVP_YES = "rsvp-yes";
+    public static final String VERB_SAVE = "save";
+    public static final String VERB_SHARE = "share";
+    public static final String VERB_STOP_FOLLOWING = "stop-following";
+    public static final String VERB_TAG = "tag";
+    public static final String VERB_UNFAVORITE = "unfavorite";
+    public static final String VERB_UNLIKE = "unlike";
+    public static final String VERB_UNSAVE = "unsave";
+    public static final String VERB_UPDATE = "update";
+
+    public static final String OBJECT_TYPE_ARTICLE = "article";
+    public static final String OBJECT_TYPE_AUDIO = "audio";
+    public static final String OBJECT_TYPE_BADGE = "badge";
+    public static final String OBJECT_TYPE_BOOKMARK = "bookmark";
+    public static final String OBJECT_TYPE_COLLECTION = "collection";
+    public static final String OBJECT_TYPE_COMMENT = "comment";
+    public static final String OBJECT_TYPE_EVENT = "event";
+    public static final String OBJECT_TYPE_FILE = "file";
+    public static final String OBJECT_TYPE_GROUP = "group";
+    public static final String OBJECT_TYPE_IMAGE = "image";
+    public static final String OBJECT_TYPE_NOTE = "note";
+    public static final String OBJECT_TYPE_PERSON = "person";
+    public static final String OBJECT_TYPE_PLACE = "place";
+    public static final String OBJECT_TYPE_PRODUCT = "product";
+    public static final String OBJECT_TYPE_QUESTION = "question";
+    public static final String OBJECT_TYPE_REVIEW = "review";
+    public static final String OBJECT_TYPE_SERVICE = "service";
+    public static final String OBJECT_TYPE_VIDEO = "video";
+
+    protected ActivityObject actor;
+
+    protected String content;
+
+    protected ActivityObject generator;
+
+    protected MediaLink icon;
+
+    protected String category;
+
+    protected String verb;
+
+    protected Long published;
+
+    protected ActivityObject object;
+
+    // protected
+    // String objectType;
+
+    // protected
+    // String objectEntityType;
+
+    // protected
+    // String objectName;
+
+    protected String title;
+
+    protected Set<String> connections;
+
+    /**
+     * Checks if the provided type equals 'activity'.
+     *
+     * @return boolean true/false
+     */
+	public static boolean isSameType(String type) {
+		return type.equals(ENTITY_TYPE);
+	}
+	
+    /**
+     * Default constructor. Sets entity type to 'activity'.
+     */
+	public Activity() {
+		setType("activity");
+	}
+
+    /**
+     * Constructs the Activity with an instance of UGClient.
+     *
+     * @param  UGClient  an instance of UGClient
+     */
+    public Activity(UGClient client) {
+    	super(client);
+        setType("activity");
+    }
+
+    /**
+     * Constructs the Activity with an instance of UGClient and
+     * an entity UUID.
+     *
+     * @param  UGClient  an instance of UGClient
+     * @param  id  the UUID of the activity entity
+     */
+    public Activity(UGClient client, UUID id) {
+        this(client);
+        setUuid(id);
+    }
+
+    /**
+     * Creates a new Activity object.
+     *
+     * @param  UGClient  an instance of UGClient
+     * @param  verb  the 'verb' to associate with the activity, e.g. 'uploaded', 'posted', etc
+     * @param  title  the title of the activity
+     * @param  content  the content of the posted activity
+     * @param  category  the category of the activity
+     * @param  user  an Entity object that represents the 'actor', i.e. the user performing the activity.
+     *      If the name property is set it will be used for the display name of the actor,
+     *      otherwise the username will be used.
+     * @param  object  the Entity object that is acted on, e.g. the article posted, the image uploaded, etc.
+     * @param  objectType  the type of activity object, e.g. article, group, review, etc.
+     * @param  objectName  optional. The name of the activity object, e.g. 
+     * @param  objectContent  optional. The content of the object, e.g. a link to a posted photo
+     * @return an Activity object
+     */
+    public static Activity newActivity(UGClient client, String verb, String title,
+            String content, String category, Entity user, Entity object,
+            String objectType, String objectName, String objectContent){
+
+        Activity activity = new Activity(client);
+        activity.setVerb(verb);
+        activity.setCategory(category);
+        activity.setContent(content);
+        activity.setTitle(title);
+        
+        ActivityObject actor = new ActivityObject();
+        actor.setObjectType("person");
+        
+        if (user != null) {            
+            if(user.getStringProperty("name") != null) {
+        	   actor.setDisplayName(user.getStringProperty("name"));
+            } else {
+               actor.setDisplayName(user.getStringProperty("username"));
+            }
+            actor.setEntityType(user.getType());
+            actor.setUuid(user.getUuid());
+        }
+        
+        activity.setActor(actor);
+
+        ActivityObject obj = new ActivityObject();
+        obj.setDisplayName(objectName);
+        obj.setObjectType(objectType);
+        if (object != null) {
+            obj.setEntityType(object.getType());
+            obj.setUuid(object.getUuid());
+        }
+        if (objectContent != null) {
+            obj.setContent(objectContent);
+        } else {
+            obj.setContent(content);
+        }
+        activity.setObject(obj);
+
+        return activity;
+    }
+
+    /**
+     * Gets the 'actor' of the activity
+     *
+     * @return  an ActivityObject that represents the actor
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public ActivityObject getActor() {
+        return actor;
+    }
+
+    /**
+     * Sets the 'actor' of the activity
+     *
+     * @param  actor  an ActivityObject that represents the actor
+     */
+    public void setActor(ActivityObject actor) {
+        this.actor = actor;
+    }
+
+    /**
+     * Gets the activity generator, i.e. a link to the application that
+     * generated the activity object.
+     *
+     * @return  the generator
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public ActivityObject getGenerator() {
+        return generator;
+    }
+
+    /**
+     * Sets the activity generator, i.e. a link to the application that
+     * generated the activity object.
+     *
+     * @param  generator  the generator
+     */
+    public void setGenerator(ActivityObject generator) {
+        this.generator = generator;
+    }
+
+    /*
+     * @JsonSerialize(include = Inclusion.NON_NULL) public String getActorName()
+     * { return actorName; }
+     * 
+     * public void setActorName(String actorName) { this.actorName = actorName;
+     * }
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    /**
+     * Gets the verb of the Activity.
+     *
+     * @return  the activity verb
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public String getVerb() {
+        return verb;
+    }
+
+    /**
+     * Sets the verb of the Activity.
+     *
+     * @param  verb  the verb
+     */
+    public void setVerb(String verb) {
+        this.verb = verb;
+    }
+
+    /**
+     * Retrieves the UNIX timestamp of when the activity was published.
+     *
+     * @return a UNIX timestamp
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public Long getPublished() {
+        return published;
+    }
+
+    /**
+     * Sets the UNIX timestamp of when the activity was published.
+     *
+     * @param  published  a UNIX timestamp
+     */
+    public void setPublished(Long published) {
+        this.published = published;
+    }
+
+    /**
+     * Retrieves the object of the activity.
+     *
+     * @return  an ActivityObject representing the object
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public ActivityObject getObject() {
+        return object;
+    }
+
+    /**
+     * Sets the object of the activity.
+     *
+     * @param  object  an ActivityObject representing the object
+     */
+    public void setObject(ActivityObject object) {
+        this.object = object;
+    }
+
+    /*
+     * @JsonSerialize(include = Inclusion.NON_NULL) public String
+     * getObjectType() { return objectType; }
+     * 
+     * public void setObjectType(String objectType) { this.objectType =
+     * objectType; }
+     * 
+     * @JsonSerialize(include = Inclusion.NON_NULL) public String
+     * getObjectEntityType() { return objectEntityType; }
+     * 
+     * public void setObjectEntityType(String objectEntityType) {
+     * this.objectEntityType = objectEntityType; }
+     * 
+     * @JsonSerialize(include = Inclusion.NON_NULL) public String
+     * getObjectName() { return objectName; }
+     * 
+     * public void setObjectName(String objectName) { this.objectName =
+     * objectName; }
+     */
+
+    /**
+     * Retrieves the title of the activity
+     *
+     * @return the title
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Sets the title of the Activity
+     *
+     * @param  title  the title
+     */
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * Gets the icon to display with the Activity.
+     *
+     * @return  a MediaLink object that represents the icon
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public MediaLink getIcon() {
+        return icon;
+    }
+
+    /**
+     * Sets the icon to display with the Activity.
+     *
+     * @param  icon  a MediaLink object that represents the icon
+     */
+    public void setIcon(MediaLink icon) {
+        this.icon = icon;
+    }
+
+    /**
+     * Retrieves the content of the Activity.
+     *
+     * @return  the activity content
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public String getContent() {
+        return content;
+    }
+
+    /**
+     * Sets the content of the Activity.
+     *
+     * @param  content  the activity content
+     */
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    /**
+     * Gets the entity connections for the activity.
+     *
+     * @return  the connections as a Set object
+     */
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    public Set<String> getConnections() {
+        return connections;
+    }
+
+    /**
+     * Stores the entity connections for the activity.
+     *
+     * @param  connections  the connections as a Set object
+     */
+    public void setConnections(Set<String> connections) {
+        this.connections = connections;
+    }
+
+    /**
+     * Models a media object, such as an image.
+     */
+    //@XmlRootElement
+    static public class MediaLink {
+
+        int duration;
+
+        int height;
+
+        String url;
+
+        int width;
+
+        protected Map<String, Object> dynamic_properties = new TreeMap<String, Object>(
+                String.CASE_INSENSITIVE_ORDER);
+
+        /**
+         * Default constructor.
+         */
+        public MediaLink() {
+        }
+
+        /**
+         * Retrieves the duration of the media, e.g. the length of a video.
+         *
+         * @return the duration
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public int getDuration() {
+            return duration;
+        }
+
+        /**
+         * Sets the duration of the media, e.g. the length of a video.
+         *
+         * @param  duration  the duration
+         */
+        public void setDuration(int duration) {
+            this.duration = duration;
+        }
+
+        /**
+         * Retrieves the height of the media, e.g. height of the image.
+         *
+         * @return the height
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public int getHeight() {
+            return height;
+        }
+
+        /**
+         * Sets the height of the media, e.g. height of the image.
+         *
+         * @param  height  the height
+         */
+        public void setHeight(int height) {
+            this.height = height;
+        }
+
+        /**
+         * Retrieves the url of the media, e.g. url a video can be streamed from.
+         *
+         * @return the url
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getUrl() {
+            return url;
+        }
+
+        /**
+         * Sets the url of the media, e.g. url a video can be streamed from.
+         *
+         * @param  url  the url
+         */
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        /**
+         * Retrieves the width of the media, e.g. image width.
+         *
+         * @return the width
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public int getWidth() {
+            return width;
+        }
+
+        /**
+         * Sets the width of the media, e.g. image width.
+         *
+         * @param  width  the width
+         */
+        public void setWidth(int width) {
+            this.width = width;
+        }
+
+        @JsonAnySetter
+        public void setDynamicProperty(String key, Object value) {
+            dynamic_properties.put(key, value);
+        }
+
+        @JsonAnyGetter
+        public Map<String, Object> getDynamicProperties() {
+            return dynamic_properties;
+        }
+
+        /**
+         * Returns the properties of the MediaLink object as a string.
+         *
+         * @return the object properties
+         */
+        @Override
+        public String toString() {
+            return "MediaLink [duration=" + duration + ", height=" + height
+                    + ", url=" + url + ", width=" + width
+                    + ", dynamic_properties=" + dynamic_properties + "]";
+        }
+
+    }
+
+    /**
+     * Models the object of an activity. For example, for the activity
+     * 'John posted a new article', the article is the activity object.
+     */
+    //@XmlRootElement
+    static public class ActivityObject {
+
+        ActivityObject[] attachments;
+
+        ActivityObject author;
+
+        String content;
+
+        String displayName;
+
+        String[] downstreamDuplicates;
+
+        String id;
+
+        MediaLink image;
+
+        String objectType;
+
+        Date published;
+
+        String summary;
+
+        String updated;
+
+        String upstreamDuplicates;
+
+        String url;
+
+        UUID uuid;
+
+        String entityType;
+
+        protected Map<String, Object> dynamic_properties = new TreeMap<String, Object>(
+                String.CASE_INSENSITIVE_ORDER);
+
+        /**
+         * Default constructor.
+         */
+        public ActivityObject() {
+        }
+
+        /**
+         * Gets the attachments for the activity
+         *
+         * @return an array of ActivityObject objects that represent the attachments
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public ActivityObject[] getAttachments() {
+            return attachments;
+        }
+
+        /**
+         * Sets the attachments for the activity
+         *
+         * @param  attachments  an array of ActivityObject objects that represent the attachments
+         */
+        public void setAttachments(ActivityObject[] attachments) {
+            this.attachments = attachments;
+        }
+
+        /**
+         * Gets the author who posted the activity. This can be distinct from
+         * the actor, who is the user that performed the activity.
+         * 
+         * @return an ActivityObject that represents the author
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public ActivityObject getAuthor() {
+            return author;
+        }
+
+        /**
+         * Sets the author who posted the activity. This can be distinct from
+         * the actor, who is the user that performed the activity.
+         * 
+         * @param  author  an ActivityObject that represents the author
+         */
+        public void setAuthor(ActivityObject author) {
+            this.author = author;
+        }
+
+        /**
+         * Gets the content of the activity.
+         *
+         * @return  the activity content
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getContent() {
+            return content;
+        }
+
+        /**
+         * Sets the content of the activity.
+         *
+         * @param  content  the activity content
+         */
+        public void setContent(String content) {
+            this.content = content;
+        }
+
+        /**
+         * Gets the display name of the activity.
+         *
+         * @return  the dislay name
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getDisplayName() {
+            return displayName;
+        }
+
+        /**
+         * Sets the display name of the activity.
+         *
+         * @param  displayName  the dislay name
+         */
+        public void setDisplayName(String displayName) {
+            this.displayName = displayName;
+        }
+
+        /**
+         * Gets the IRIs identifying objects that duplicate this object's content.
+         *
+         * @return An array of one or more absolute IRIs
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String[] getDownstreamDuplicates() {
+            return downstreamDuplicates;
+        }
+
+        /**
+         * Sets the IRIs identifying objects that duplicate this object's content.
+         *
+         * @param  downstreamDuplicates  An array of one or more absolute IRIs
+         */
+        public void setDownstreamDuplicates(String[] downstreamDuplicates) {
+            this.downstreamDuplicates = downstreamDuplicates;
+        }
+
+        /**
+         * Gets the id of this object. Should be universally unique.
+         *
+         * @return  the id
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getId() {
+            return id;
+        }
+
+        /**
+         * Sets the id of this object. Should be universally unique.
+         *
+         * @param  id  the id
+         */
+        public void setId(String id) {
+            this.id = id;
+        }
+
+        /**
+         * Gets the image associated with this object.
+         *
+         * @return  a MediaLink object that describes the image
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public MediaLink getImage() {
+            return image;
+        }
+
+        /**
+         * Sets the image associated with this object.
+         *
+         * @param  image  a MediaLink object that describes the image
+         */
+        public void setImage(MediaLink image) {
+            this.image = image;
+        }
+
+        /**
+         * Gets the object type associated with this object.
+         *
+         * @return  the type of the object
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getObjectType() {
+            return objectType;
+        }
+
+        /**
+         * Sets the object type associated with this object.
+         *
+         * @param  objectType  the type of the object
+         */
+        public void setObjectType(String objectType) {
+            this.objectType = objectType;
+        }
+
+        /**
+         * Gets the date this object was published.
+         *
+         * @return the date
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public Date getPublished() {
+            return published;
+        }
+
+        /**
+         * Sets the date this object was published.
+         *
+         * @param  published  the date
+         */
+        public void setPublished(Date published) {
+            this.published = published;
+        }
+
+        /**
+         * Gets the summary for this object.
+         *
+         * @return the summary
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getSummary() {
+            return summary;
+        }
+
+        /**
+         * Sets the summary for this object.
+         *
+         * @param  summary  the summary
+         */
+        public void setSummary(String summary) {
+            this.summary = summary;
+        }
+
+        /**
+         * Gets the date this object was last updated.
+         *
+         * @return the updated date
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getUpdated() {
+            return updated;
+        }
+
+        /**
+         * Sets the date this object was last updated.
+         *
+         * @param  updated  the updated date
+         */
+        public void setUpdated(String updated) {
+            this.updated = updated;
+        }
+
+        /**
+         * Gets the IRIs identifying objects that this object's content duplicates.
+         *
+         * @return A JSON Array of one or more absolute IRIs
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getUpstreamDuplicates() {
+            return upstreamDuplicates;
+        }
+
+        /**
+         * Sets the IRIs identifying objects that this object's content duplicates.
+         *
+         * @param  upstreamDuplicates  A JSON Array of one or more absolute IRIs
+         */
+        public void setUpstreamDuplicates(String upstreamDuplicates) {
+            this.upstreamDuplicates = upstreamDuplicates;
+        }
+
+        /**
+         * Gets the url for the entity that corresponds to this object
+         *
+         * @return the URL
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getUrl() {
+            return url;
+        }
+
+        /**
+         * Sets the url for the entity that corresponds to this object
+         *
+         * @param  url  the URL
+         */
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        /**
+         * Gets the UUID for the entity this object is modeling.
+         *
+         * @return the UUID
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public UUID getUuid() {
+            return uuid;
+        }
+
+        /**
+         * Sets the UUID for the entity this object is modeling.
+         *
+         * @param  uuid  a UUID object
+         */
+        public void setUuid(UUID uuid) {
+            this.uuid = uuid;
+        }
+
+        /**
+         * Gets the entity type for the entity this object is modeling.
+         *
+         * @return the entity type
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getEntityType() {
+            return entityType;
+        }
+
+        /**
+         * Sets the entity type for the entity this object is modeling.
+         *
+         * @param  entityType  the entity type
+         */
+        public void setEntityType(String entityType) {
+            this.entityType = entityType;
+        }
+
+        @JsonAnySetter
+        public void setDynamicProperty(String key, Object value) {
+            dynamic_properties.put(key, value);
+        }
+
+        @JsonAnyGetter
+        public Map<String, Object> getDynamicProperties() {
+            return dynamic_properties;
+        }
+
+        /**
+         * Returns the properties of the ActivityObject as a string.
+         *
+         * @return the object properties
+         */        
+        @Override
+        public String toString() {
+            return "ActivityObject [attachments="
+                    + Arrays.toString(attachments) + ", author=" + author
+                    + ", content=" + content + ", displayName=" + displayName
+                    + ", downstreamDuplicates="
+                    + Arrays.toString(downstreamDuplicates) + ", id=" + id
+                    + ", image=" + image + ", objectType=" + objectType
+                    + ", published=" + published + ", summary=" + summary
+                    + ", updated=" + updated + ", upstreamDuplicates="
+                    + upstreamDuplicates + ", url=" + url + ", uuid=" + uuid
+                    + ", entityType=" + entityType + ", dynamic_properties="
+                    + dynamic_properties + "]";
+        }
+
+    }
+
+    /**
+     * Models the feed from an activity stream as a collection
+     * of individual Activity objects.
+     */
+    //@XmlRootElement
+    static public class ActivityCollection {
+
+        int totalItems;
+
+        ActivityObject[] items;
+
+        String url;
+
+        protected Map<String, Object> dynamic_properties = new TreeMap<String, Object>(
+                String.CASE_INSENSITIVE_ORDER);
+
+        /**
+         * Default constructor.
+         */
+        public ActivityCollection() {
+        }
+
+        /**
+         * Gets a count of the number of activities
+         *
+         * @return  the activity count
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public int getTotalItems() {
+            return totalItems;
+        }
+
+        /**
+         * @y.exclude
+         */
+        public void setTotalItems(int totalItems) {
+            this.totalItems = totalItems;
+        }
+
+        /**
+         * Gets an array of the activities.
+         *
+         * @return  an array of ActivityObject objects
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public ActivityObject[] getItems() {
+            return items;
+        }
+
+        /**
+         * @y.exclude
+         */
+        public void setItems(ActivityObject[] items) {
+            this.items = items;
+        }
+
+        /**
+         * Gets the url for the activity feed.
+         *
+         * @return  the URL
+         */
+        @JsonSerialize(include = Inclusion.NON_NULL)
+        public String getUrl() {
+            return url;
+        }
+
+        /**
+         * @y.exclude
+         */
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        @JsonAnySetter
+        public void setDynamicProperty(String key, Object value) {
+            dynamic_properties.put(key, value);
+        }
+
+        @JsonAnyGetter
+        public Map<String, Object> getDynamicProperties() {
+            return dynamic_properties;
+        }
+
+        /**
+         * Returns the properties of the ActivityCollection as a string.
+         *
+         * @return the object properties
+         */
+        @Override
+        public String toString() {
+            return "ActivityCollection [totalItems=" + totalItems + ", items="
+                    + Arrays.toString(items) + ", url=" + url
+                    + ", dynamic_properties=" + dynamic_properties + "]";
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Collection.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Collection.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Collection.java
new file mode 100755
index 0000000..359b596
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Collection.java
@@ -0,0 +1,319 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import org.apache.usergrid.android.sdk.UGClient.Query;
+import org.apache.usergrid.android.sdk.response.ApiResponse;
+
+/**
+ * Models a collection of entities as a local object. Collections
+ * are the primary way that entities are organized in Usergrid.
+ *
+ * @see <a href="http://apigee.com/docs/app-services/content/collections">Collections documentation</a>
+ */
+public class Collection
+{
+	private UGClient client;
+	private String type;
+	private Map<String,Object> qs;
+
+	private ArrayList<Entity> list;
+	private int iterator;
+	private ArrayList<String> previous;
+	private String next;
+	private String cursor;
+
+	/**
+	 * Default constructor for a Collection object.
+	 *
+	 * @param  UGClient  an instance of the UGClient class
+	 * @param  type  the entity 'type' associated with the colleciton
+	 * @param  qs  optional Map object of query parameters to apply to the collection retrieval
+	 */	
+	public Collection(UGClient client, String type, Map<String,Object> qs) {
+	    this.client = client;
+	    this.type = type;
+	    
+	    if( qs == null )
+	    {
+	    	this.qs = new HashMap<String,Object>();
+	    }
+	    else
+	    {
+	    	this.qs = qs;
+	    }
+
+	    this.list = new ArrayList<Entity>();
+	    this.iterator = -1;
+
+	    this.previous = new ArrayList<String>();
+	    this.next = null;
+	    this.cursor = null;
+
+	    this.fetch();
+	}
+
+	/**
+	 * Gets the entity 'type' associated with the collection.
+	 *
+	 * @return the collection type
+	 */	
+	public String getType(){
+	   return this.type;
+	}
+	
+	/**
+	 * Sets the entity 'type' associated with the collection.
+	 *
+	 * @param  type  the collection type
+	 */	
+	public void setType(String type){
+	   this.type = type;
+	}
+
+	/**
+	 * Retrieves the current state of the collection from the server, and populates
+	 * an the Collection object with the returned set of entities. Executes synchronously.
+	 *
+	 * @return  an ApiResponse object
+	 */	
+	public ApiResponse fetch() {
+	    if (this.cursor != null) {
+	    	this.qs.put("cursor", this.cursor);
+	    }
+	    
+	    Query query = this.client.queryEntitiesRequest("GET", this.qs, null,
+                this.client.getOrganizationId(),  this.client.getApplicationId(), this.type);
+	    ApiResponse response = query.getResponse();
+	    if (response.getError() != null) {
+	    	this.client.writeLog("Error getting collection.");
+	    } else {
+	    	String theCursor = response.getCursor();
+    		int count = response.getEntityCount();
+    		
+    		UUID nextUUID = response.getNext();
+    		if( nextUUID != null ) {
+    			this.next = nextUUID.toString();
+    		} else {
+    			this.next = null;
+    		}
+    		this.cursor = theCursor;
+
+	    	this.saveCursor(theCursor);
+	    	if ( count > 0 ) {
+	    		this.resetEntityPointer();
+	    		this.list = new ArrayList<Entity>();
+	    		List<Entity> retrievedEntities = response.getEntities();
+	    		
+	    		for ( Entity retrievedEntity : retrievedEntities ) {
+	    			if( retrievedEntity.getUuid() != null ) {
+	    				retrievedEntity.setType(this.type);
+	    				this.list.add(retrievedEntity);
+	    			}
+	    		}
+	    	}
+	    }
+	    
+	    return response;
+	}
+
+	/**
+	 * Adds an entity to the Collection object.
+	 *
+	 * @param  entityData  a Map object of entity properties to be saved in the entity
+	 * @return  an Entity object that represents the newly added entity. Must include
+	 *		a 'type' property. Executes synchronously.
+	 */	
+	public Entity addEntity(Map<String,Object> entityData) {
+		Entity entity = null;		
+		ApiResponse response = this.client.createEntity(entityData);
+		if( (response != null) && (response.getError() == null) && (response.getEntityCount() > 0) ) {
+			entity = response.getFirstEntity();
+			if (entity != null) {
+				this.list.add(entity);
+			}
+		}
+		return entity;
+	}
+
+	/**
+	 * Deletes the provided entity on the server, then updates the
+	 * Collection object by calling fetch(). Executes synchronously.
+	 *
+	 * @param entity an Entity object that contains a 'type' and 'uuid' property
+	 */	
+	public ApiResponse destroyEntity(Entity entity) {
+		ApiResponse response = entity.destroy();
+		if (response.getError() != null) {
+			this.client.writeLog("Could not destroy entity.");
+		} else {
+			response = this.fetch();
+		}
+	    
+		return response;
+	}
+
+	/**
+	 * Retrieves an entity from the server.
+	 *
+	 * @param uuid the UUID of the entity to retrieve
+	 * @return an ApiResponse object
+	 */	
+	public ApiResponse getEntityByUuid(UUID uuid) {
+		Entity entity = new Entity(this.client);
+	    entity.setType(this.type);
+	    entity.setUuid(uuid);
+	    return entity.fetch();
+	}
+
+	/**
+	 * Gets the first entity in the Collection object.
+	 *
+	 * @return  an Entity object
+	 */	
+	public Entity getFirstEntity() {
+		return ((this.list.size() > 0) ? this.list.get(0) : null);
+	}
+
+	/**
+	 * Gets the last entity in the Collection object.
+	 *
+	 * @return  an Entity object
+	 */	
+	public Entity getLastEntity() {
+		return ((this.list.size() > 0) ? this.list.get(this.list.size()-1) : null);
+	}
+
+	/**
+	 * Checks if there is another entity in the Collection after the current pointer position.
+	 *
+	 * @return  Boolean true/false
+	 */	
+	public boolean hasNextEntity() {
+		int next = this.iterator + 1;
+		return ((next >= 0) && (next < this.list.size()));
+	}
+
+	/**
+	 * Checks if there is an entity in the Collection before the current pointer position.
+	 *
+	 * @return  Boolean true/false
+	 */	
+	public boolean hasPrevEntity() {
+		int prev = this.iterator - 1;
+		return ((prev >= 0) && (prev < this.list.size()));
+	}
+
+	/**
+	 * Checks if there is an entity in the Collection after the current
+	 * pointer position, and returns it.
+	 *
+	 * @return an Entity object
+	 */	
+	public Entity getNextEntity() {
+		if (this.hasNextEntity()) {
+			this.iterator++;
+			return this.list.get(this.iterator);
+		}
+		return null;
+	}
+
+	/**
+	 * Checks if there is an entity in the Collection before the current
+	 * pointer position, and returns it.
+	 *
+	 * @return an Entity object
+	 */	
+	public Entity getPrevEntity() {
+		if (this.hasPrevEntity()) {
+			this.iterator--;
+			return this.list.get(this.iterator);
+		}
+		return null;
+	}
+
+	/**
+	 * Resets the pointer to the start of the Collection.
+	 */
+	public void resetEntityPointer() {
+		this.iterator = -1;
+	}
+
+	/**
+	 * Saves a pagination cursor.	 
+	 */
+	public void saveCursor(String cursor) {
+		this.next = cursor;
+	}
+
+	/**
+	 * Clears the currently saved pagination cursor from the Collection.
+	 */
+	public void resetPaging() {
+		this.previous.clear();
+		this.next = null;
+		this.cursor = null;
+	}
+
+	/**
+	 * Checks if a pagination cursor for the next result set is 
+	 * present in the Collection.
+	 *
+	 * @return Boolean true/false
+	 */
+	public boolean hasNextPage() {
+		return this.next != null;
+	}
+
+	/**
+	 * Checks if a pagination cursor for the previous result set is 
+	 * present in the Collection
+	 *
+	 * @return  Boolean true/false
+	 */
+	public boolean hasPrevPage() {
+		return !this.previous.isEmpty();
+	}
+
+	/**
+	 * Checks if a pagination cursor for the next result set is 
+	 * present in the Collection, then fetches it.
+	 *
+	 * @return an ApiResponse object if a cursor is present, otherwise null
+	 */
+	public ApiResponse getNextPage() {
+		if (this.hasNextPage()) {
+			this.previous.add(this.cursor);
+			this.cursor = this.next;
+			this.list.clear();
+			return this.fetch();
+		}
+		  
+		return null;
+	}
+
+	/**
+	 * Checks if a pagination cursor for the previous result set is 
+	 * present in the Collection, then fetches it.
+	 *
+	 * @return  an ApiResponse object if a cursor is present, otherwise null
+	 */
+	public ApiResponse getPrevPage() {
+		if (this.hasPrevPage()) {
+			this.next = null;
+			int indexOfLastObject = this.previous.size() - 1;
+			this.cursor = this.previous.get(indexOfLastObject);
+			this.previous.remove(indexOfLastObject);
+			this.list.clear();
+			return this.fetch();
+		}
+		  
+		return null;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Device.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Device.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Device.java
new file mode 100755
index 0000000..13b1e68
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Device.java
@@ -0,0 +1,103 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty;
+import static com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_NULL;
+
+import java.util.List;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * Models a 'device' entity as a local object.
+ *
+ */
+public class Device extends Entity {
+
+	public final static String ENTITY_TYPE = "device";
+
+	public final static String PROPERTY_NAME = "name";
+
+	/**
+	 * Checks if the provided type equals 'device'.
+	 *
+	 * @return  Boolean true/false
+	 */
+	public static boolean isSameType(String type) {
+		return type.equals(ENTITY_TYPE);
+	}
+
+	/**
+	 * Default constructor for the Device object. Sets 'type'
+	 * property to 'device'.
+	 */
+	public Device() {
+		setType(ENTITY_TYPE);
+	}
+	
+	/**
+	 * Constructs the Device object with a UGClient. Sets 'type'
+	 * property to 'device'.
+	 */
+	public Device(UGClient client) {
+		super(client);
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Constructs a Device object from an Entity object. If the Entity
+	 * has a 'type' property with a value other than 'device', the value
+	 * will be overwritten.
+	 */
+	public Device(Entity entity) {
+		super(entity.getUGClient());
+		properties = entity.properties;
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Returns the type of the Device object. Should always be 'device'.
+	 *
+	 * @return the String 'device'
+	 */
+	@Override
+	@JsonIgnore
+	public String getNativeType() {
+		return ENTITY_TYPE;
+	}
+
+	/**
+	 * Gets the current set of property names in the Device and adds
+	 * the 'name' property.
+	 *
+	 * @return a List object of all properties in the Device
+	 */
+	@Override
+	@JsonIgnore
+	public List<String> getPropertyNames() {
+		List<String> properties = super.getPropertyNames();
+		properties.add(PROPERTY_NAME);
+		return properties;
+	}
+
+	/**
+	 * Gets the value of the 'name' property of the Device.
+	 *
+	 * @return the value of the 'name' property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getName() {
+		return getStringProperty(PROPERTY_NAME);
+	}
+
+	/**
+	 * Sets the value of the 'name' property of the Device.
+	 *
+	 * @param  name  the value of the 'name' property
+	 */
+	public void setName(String name) {
+		setStringProperty(properties, PROPERTY_NAME, name);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Entity.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Entity.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Entity.java
new file mode 100755
index 0000000..5796a8a
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Entity.java
@@ -0,0 +1,533 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.getUUIDProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setBooleanProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setFloatProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setLongProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setUUIDProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.toJsonString;
+import static org.apache.usergrid.android.sdk.utils.MapUtils.newMapWithoutKeys;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import org.apache.usergrid.android.sdk.UGClient.Query;
+import org.apache.usergrid.android.sdk.response.ApiResponse;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Models an entity of any type as a local object. Type-specific 
+ * classes are extended from this class.
+ *
+ * @see <a href="http://apigee.com/docs/app-services/content/app-services-data-model-1">Usergrid data model documentation</a>
+ */
+public class Entity {
+
+    public final static String PROPERTY_UUID      = "uuid";
+    public final static String PROPERTY_TYPE      = "type";
+    public final static String PROPERTY_NAME      = "name";
+    public final static String PROPERTY_METADATA  = "metadata";
+    public final static String PROPERTY_CREATED   = "created";
+    public final static String PROPERTY_MODIFIED  = "modified";
+    public final static String PROPERTY_ACTIVATED = "activated";
+    
+
+    protected Map<String, JsonNode> properties = new HashMap<String, JsonNode>();
+    private UGClient client;
+
+    public static Map<String, Class<? extends Entity>> CLASS_FOR_ENTITY_TYPE = new HashMap<String, Class<? extends Entity>>();
+    static {
+        CLASS_FOR_ENTITY_TYPE.put(User.ENTITY_TYPE, User.class);
+    }
+
+    /**
+     * Default constructor for instantiating an Entity object.
+     */
+    public Entity() {	
+    }
+    
+    /**
+     * Constructor for instantiating an Entity with a UGClient.
+     * @param  UGClient  a UGClient object
+     */
+    public Entity(UGClient client) {
+    	this.client = client;
+    }
+
+    /**
+     * Constructor for instantiating an Entity with a UGClient
+     * and entity type. Normally this is the constructor that should
+     * be used to model an entity locally.
+     * @param  UGClient  a UGClient object
+     * @param  type  the 'type' property of the entity
+     */
+    public Entity(UGClient client, String type) {
+    	this.client = client;
+        setType(type);
+    }
+    
+    /**
+     * Gets the UGClient currently saved in the Entity object.
+     * @return the UGClient instance
+     */
+    public UGClient getUGClient() {
+    	return client;
+    }
+
+    /**
+     * Sets the UGClient in the Entity object.
+     * @param  UGClient  the UGClient instance
+     */
+    public void setUGClient(UGClient client) {
+        this.client = client;
+    }
+
+    /**
+     * Gets the 'type' of the Entity object.
+     * @return the 'type' of the entity
+     */
+    @JsonIgnore
+    public String getNativeType() {
+        return getType();
+    }
+
+    /**
+     * Adds the type and UUID properties to the Entity object, then 
+     * returns all object properties.
+     * @return a List object with the entity UUID and type
+     */
+    @JsonIgnore
+    public List<String> getPropertyNames() {
+        List<String> properties = new ArrayList<String>();
+        properties.add(PROPERTY_TYPE);
+        properties.add(PROPERTY_UUID);
+        return properties;
+    }
+
+    /**
+     * Gets the String value of the specified Entity property.
+     * @param  name  the name of the property
+     * @return the property value. Returns null if the property has no value
+     */
+    public String getStringProperty(String name) {
+        JsonNode val = this.properties.get(name);
+        return val != null ? val.textValue() : null;
+    }
+    
+    /**
+     * Gets the boolean value of the specified Entity property.
+     * @param  name  the name of the property
+     * @return the property value
+     */
+    public boolean getBoolProperty(String name) {
+    	return this.properties.get(name).booleanValue();
+    }
+    
+    /**
+     * Gets the Int value of the specified Entity property.
+     * @param  name  the name of the property
+     * @return the property value
+     */
+    public int getIntProperty(String name) {
+    	return this.properties.get(name).intValue();
+    }
+    
+    /**
+     * Gets the Double value of the specified Entity property.
+     * @param  name  the name of the property
+     * @return the property value
+     */
+    public double getDoubleProperty(String name) {
+    	return this.properties.get(name).doubleValue();
+    }
+    
+    /**
+     * Gets the long value of the specified Entity property.
+     * @param  name  the name of the property
+     * @return the property value
+     */
+    public long getLongProperty(String name) {
+    	return this.properties.get(name).longValue();
+    }
+
+    /**
+     * Gets the 'type' property of the Entity object.     
+     * @return the Entity type
+     */
+    public String getType() {
+        return getStringProperty(PROPERTY_TYPE);
+    }
+
+    /**
+     * Sets the 'type' property of the Entity object.          
+     * @param  type  the entity type
+     */
+    public void setType(String type) {
+        setStringProperty(properties, PROPERTY_TYPE, type);
+    }
+
+    /**
+     * Gets the 'uuid' property of the Entity object.     
+     * @return the Entity UUID
+     */
+    public UUID getUuid() {
+        return getUUIDProperty(properties, PROPERTY_UUID);
+    }
+
+    /**
+     * Sets the 'uuid' property of the Entity object.     
+     * @param  uuid  the entity UUID
+     */
+    public void setUuid(UUID uuid) {
+        setUUIDProperty(properties, PROPERTY_UUID, uuid);
+    }
+
+    /**
+     * Returns a HashMap of the Entity properties without keys.
+     *
+     * @return a HashMap object with no keys and the value of the Entity properties
+     */
+    @JsonAnyGetter
+    public Map<String, JsonNode> getProperties() {
+        return newMapWithoutKeys(properties, getPropertyNames());
+    }
+
+    /**
+     * Adds a property to the Entity object.
+     *
+     * @param  name  the name of the property to be set
+     * @param  value the value of the property as a JsonNode object.
+     *      If the value is null, the property will be removed from the object.
+     * @see  <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> 
+     */
+    @JsonAnySetter
+    public void setProperty(String name, JsonNode value) {
+        if (value == null) {
+            properties.remove(name);
+        } else {
+            properties.put(name, value);
+        }
+    }
+    
+    /**
+     * Removes all properties from the Entity object, then adds multiple properties.
+     *
+     * @param  newProperties  a Map object that contains the 
+     *      property names as keys and their values as values.
+     *      Property values must be JsonNode objects. If the value 
+     *      is null, the property will be removed from the object.
+     * @see  <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> 
+     */
+    public void setProperties(Map<String,JsonNode> newProperties) {
+    	properties.clear();
+    	Set<String> keySet = newProperties.keySet();
+    	Iterator<String> keySetIter = keySet.iterator();
+    	
+    	while( keySetIter.hasNext() ) {
+    		String key = keySetIter.next();
+    		setProperty(key, newProperties.get(key));
+    	}
+    }
+  
+    /**
+     * Adds a property to the Entity object with a String value.
+     * 
+     * @param  name  the name of the property to be set
+     * @param  value  the String value of the property
+     */
+    public void setProperty(String name, String value) {
+        setStringProperty(properties, name, value);
+    }
+
+    /**
+     * Adds a property to the Entity object with a boolean value.
+     * 
+     * @param  name  the name of the property to be set
+     * @param  value  the boolean value of the property
+     */
+    public void setProperty(String name, boolean value) {
+        setBooleanProperty(properties, name, value);
+    }
+
+    /**
+     * Adds a property to the Entity object with a long value.
+     * 
+     * @param  name  the name of the property to be set
+     * @param  value  the long value of the property
+     */
+    public void setProperty(String name, long value) {
+        setLongProperty(properties, name, value);
+    }
+
+    /**
+     * Adds a property to the Entity object with a int value.
+     * 
+     * @param  name  the name of the property to be set
+     * @param  value  the int value of the property
+     */
+    public void setProperty(String name, int value) {
+        setProperty(name, (long) value);
+    }
+
+    /**
+     * Adds a property to the Entity object with a float value.
+     * 
+     * @param  name  the name of the property to be set
+     * @param  value  the float value of the property
+     */
+    public void setProperty(String name, float value) {
+        setFloatProperty(properties, name, value);
+    }
+
+    /**
+     * Returns the Entity object as a JSON-formatted string
+     */
+    @Override
+    public String toString() {
+        return toJsonString(this);
+    }
+
+    /**
+     * @y.exclude
+     */
+    public <T extends Entity> T toType(Class<T> t) {
+        return toType(this, t);
+    }
+
+    /**
+     * @y.exclude
+     */
+    public static <T extends Entity> T toType(Entity entity, Class<T> t) {
+        if (entity == null) {
+            return null;
+        }
+        T newEntity = null;
+        if (entity.getClass().isAssignableFrom(t)) {
+            try {
+                newEntity = (t.newInstance());
+                if ((newEntity.getNativeType() != null)
+                        && newEntity.getNativeType().equals(entity.getType())) {
+                    newEntity.properties = entity.properties;
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return newEntity;
+    }
+
+    /**
+     * @y.exclude
+     */
+    public static <T extends Entity> List<T> toType(List<Entity> entities,
+            Class<T> t) {
+        List<T> l = new ArrayList<T>(entities != null ? entities.size() : 0);
+        if (entities != null) {
+            for (Entity entity : entities) {
+                T newEntity = entity.toType(t);
+                if (newEntity != null) {
+                    l.add(newEntity);
+                }
+            }
+        }
+        return l;
+    }
+    
+    /**
+     * Fetches the current state of the entity from the server and saves
+     * it in the Entity object. Runs synchronously.
+     *      
+     * @return an ApiResponse object
+     */
+    public ApiResponse fetch() {
+    	ApiResponse response = new ApiResponse();
+        String type = this.getType();
+        UUID uuid = this.getUuid(); // may be NULL
+        String entityId = null;
+        if ( uuid != null ) {        	
+        	entityId = uuid.toString();
+        } else {
+        	if (User.isSameType(type)) {
+                String username = this.getStringProperty(User.PROPERTY_USERNAME);
+                if ((username != null) && (username.length() > 0)) {            	    
+            	    entityId = username;
+                } else {
+                    String error = "no_username_specified";
+                    this.client.writeLog(error);
+                    response.setError(error);
+                    //response.setErrorCode(error);
+                    return response;
+                }
+            } else {
+                String name = this.getStringProperty(PROPERTY_NAME);
+                if ((name != null) && (name.length() > 0)) {                    
+                    entityId = name;
+                } else {
+                    String error = "no_name_specified";
+                    this.client.writeLog(error);
+                    response.setError(error);
+                    //response.setErrorCode(error);
+                    return response;
+                }
+            }
+        }
+        
+        Query q = this.client.queryEntitiesRequest("GET", null, null,
+                this.client.getOrganizationId(),  this.client.getApplicationId(), type, entityId);
+        response = q.getResponse();
+        if (response.getError() != null) {
+            this.client.writeLog("Could not get entity.");
+        } else {
+            if ( response.getUser() != null ) {
+        	    this.addProperties(response.getUser().getProperties());
+            } else if ( response.getEntityCount() > 0 ) {
+        	    Entity entity = response.getFirstEntity();
+        	    this.setProperties(entity.getProperties());
+            }
+        }
+        
+        return response;
+    }
+    
+    /**
+     * Saves the Entity object as an entity on the server. Any
+     * conflicting properties on the server will be overwritten. Runs synchronously.
+     *      
+     * @return  an ApiResponse object
+     */
+    public ApiResponse save() {
+    	ApiResponse response = null;
+        UUID uuid = this.getUuid();
+        boolean entityAlreadyExists = false;
+        
+        if (client.isUuidValid(uuid)) {
+            entityAlreadyExists = true;
+        }
+        
+        // copy over all properties except some specific ones
+        Map<String,Object> data = new HashMap<String,Object>();
+        Set<String> keySet = this.properties.keySet();
+        Iterator<String> keySetIter = keySet.iterator();
+        
+        while(keySetIter.hasNext()) {
+        	String key = keySetIter.next();
+        	if (!key.equals(PROPERTY_METADATA) &&
+        		!key.equals(PROPERTY_CREATED) &&
+        		!key.equals(PROPERTY_MODIFIED) &&
+        		!key.equals(PROPERTY_ACTIVATED) &&
+        		!key.equals(PROPERTY_UUID)) {
+        		data.put(key, this.properties.get(key));
+        	}
+        }
+        
+        if (entityAlreadyExists) {
+        	// update it
+        	response = this.client.updateEntity(uuid.toString(), data);
+        } else {
+        	// create it
+        	response = this.client.createEntity(data);
+        }
+
+        if ( response.getError() != null ) {
+            this.client.writeLog("Could not save entity.");
+        } else {
+        	if (response.getEntityCount() > 0) {
+        		Entity entity = response.getFirstEntity();
+        		this.setProperties(entity.getProperties());
+        	}
+        }
+        
+        return response;    	
+    }
+    
+    /**
+     * Deletes the entity on the server.
+     *     
+     * @return  an ApiResponse object
+     */
+    public ApiResponse destroy() {
+    	ApiResponse response = new ApiResponse();
+        String type = getType();
+        String uuidAsString = null;
+        UUID uuid = getUuid();
+        if ( uuid != null ) {
+        	uuidAsString = uuid.toString();
+        } else {
+        	String error = "Error trying to delete object: No UUID specified.";
+        	this.client.writeLog(error);
+        	response.setError(error);
+        	//response.setErrorCode(error);
+        	return response;
+        }
+        
+        response = this.client.removeEntity(type, uuidAsString);
+        
+        if( (response != null) && (response.getError() != null) ) {
+        	this.client.writeLog("Entity could not be deleted.");
+        } else {
+        	this.properties.clear();
+        }
+        
+        return response;
+    }
+    
+    /**
+     * Adds multiple properties to the Entity object. Pre-existing properties will
+     * be preserved, unless there is a conflict, then the pre-existing property
+     * will be overwritten.
+     *
+     * @param  properties  a Map object that contains the 
+     *      property names as keys and their values as values.
+     *      Property values must be JsonNode objects. If the value 
+     *      is null, the property will be removed from the object.
+     * @see  <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> 
+     */
+    public void addProperties(Map<String, JsonNode> properties) {
+    	Set<String> keySet = properties.keySet();
+    	Iterator<String> keySetIter = keySet.iterator();
+    	
+    	while( keySetIter.hasNext() ) {
+    		String key = keySetIter.next();
+    		setProperty(key, properties.get(key));
+    	}
+    }
+    
+    /**
+     * Creates a connection between two entities.
+     *
+     * @param  connectType  the type of connection
+     * @param  targetEntity  the UUID of the entity to connect to
+     * @return an ApiResponse object
+     */
+    public ApiResponse connect(String connectType, Entity targetEntity) {
+    	return this.client.connectEntities(this.getType(),
+				this.getUuid().toString(),
+				connectType,
+				targetEntity.getUuid().toString());
+    }
+    
+    /**
+     * Destroys a connection between two entities.
+     *
+     * @param  connectType  the type of connection
+     * @param  targetEntity  the UUID of the entity to disconnect from
+     * @return  an ApiResponse object
+     */
+    public ApiResponse disconnect(String connectType, Entity targetEntity) {
+    	return this.client.disconnectEntities(this.getType(),
+    												this.getUuid().toString(),
+    												connectType,
+    												targetEntity.getUuid().toString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Group.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Group.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Group.java
new file mode 100755
index 0000000..bd68427
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Group.java
@@ -0,0 +1,132 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty;
+import static com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_NULL;
+
+import java.util.List;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * Models the 'group' entity as a local object. The group entity is
+ * primarily used as a way of grouping users, but can be used to group
+ * any entity.
+ *
+ * @see <a href="http://apigee.com/docs/app-services/content/group">Group entity documentation</a>
+ */
+public class Group extends Entity {
+
+	public final static String ENTITY_TYPE = "group";
+
+	public final static String PROPERTY_PATH  = "path";
+	public final static String PROPERTY_TITLE = "title";
+
+	/**
+	 * Checks if the provided 'type' equals 'group'.
+	 *
+	 * @param  type  the type to compare
+	 * @return  Boolean true/false
+	 */
+	public static boolean isSameType(String type) {
+		return type.equals(ENTITY_TYPE);
+	}
+
+	/**
+	 * Default constructor for the Group object. Sets the 'type'
+	 * property to 'group'.	 
+	 */
+	public Group() {
+		setType(ENTITY_TYPE);
+	}
+	
+	/**
+	 * Constructs the Group object with a UGClient. Sets the 'type'
+	 * property to 'group'.
+	 *
+	 * @param UGClient an instance of UGClient
+	 */
+	public Group(UGClient client) {
+		super(client);
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Constructs the Group object from an Entity object. If the 'type'
+	 * property of the Entity is not 'group' it will be overwritten.
+	 *
+	 * @param  entity  an Entity object
+	 */
+	public Group(Entity entity) {
+		super(entity.getUGClient());
+		properties = entity.properties;
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Returns the valye of the 'type' property of the Group object.
+	 * Should always be 'group'.
+	 *
+	 * @return  the String 'group'
+	 */
+	@Override
+	@JsonIgnore
+	public String getNativeType() {
+		return ENTITY_TYPE;
+	}
+
+	/**
+	 * Gets all the current property names in the Group object and adds
+	 * the 'path' and 'title' properties.
+	 *
+	 * @return  a List object that contains the properties list
+	 */
+	@Override
+	@JsonIgnore
+	public List<String> getPropertyNames() {
+		List<String> properties = super.getPropertyNames();
+		properties.add(PROPERTY_PATH);
+		properties.add(PROPERTY_TITLE);
+		return properties;
+	}
+
+	/**
+	 * Gets the value of the 'path' property of the Group object.
+	 *
+	 * @return  the value of the 'path' property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getPath() {
+		return getStringProperty(PROPERTY_PATH);
+	}
+
+	/**
+	 * Sets the value of the 'path' property of the Group object.
+	 *
+	 * @param  path  the value of the 'path' property
+	 */
+	public void setPath(String path) {
+		setStringProperty(properties, PROPERTY_PATH, path);
+	}
+
+	/**
+	 * Gets the value of the 'title' property of the Group object.
+	 *
+	 * @return  the value of the 'title' property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getTitle() {
+		return getStringProperty(PROPERTY_TITLE);
+	}
+
+	/**
+	 * Sets the value of the 'title' property of the Group object.
+	 *
+	 * @param  title  the value of the 'title' property
+	 */
+	public void setTitle(String title) {
+		setStringProperty(properties, PROPERTY_TITLE, title);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Message.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Message.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Message.java
new file mode 100755
index 0000000..65aca4c
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/Message.java
@@ -0,0 +1,140 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.getBooleanProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.getUUIDProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setBooleanProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setLongProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setUUIDProperty;
+import static com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_NULL;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import org.apache.usergrid.android.sdk.utils.JsonUtils;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+public class Message extends Entity {
+
+	public static final String ENTITY_TYPE = "message";
+
+	public static final String PROPERTY_CORRELATION_ID = "correlation_id";
+	public static final String PROPERTY_DESTINATION = "destination";
+	public static final String PROPERTY_REPLY_TO = "reply_to";
+	public static final String PROPERTY_TIMESTAMP = "timestamp";
+	public static final String PROPERTY_TYPE = "type";
+	public static final String PROPERTY_CATEGORY = "category";
+	public static final String PROPERTY_INDEXED = "indexed";
+	public static final String PROPERTY_PERSISTENT = "persistent";
+
+	public static boolean isSameType(String type) {
+		return type.equals(ENTITY_TYPE);
+	}
+
+	public Message() {
+		setType(ENTITY_TYPE);
+	}
+	
+	public Message(UGClient client) {
+		super(client);
+		setType(ENTITY_TYPE);
+	}
+
+	public Message(Entity entity) {
+		super(entity.getUGClient());
+		properties = entity.properties;
+		setType(ENTITY_TYPE);
+	}
+
+	@Override
+	@JsonIgnore
+	public String getNativeType() {
+		return ENTITY_TYPE;
+	}
+
+	@Override
+	@JsonIgnore
+	public List<String> getPropertyNames() {
+		List<String> properties = super.getPropertyNames();
+		properties.add(PROPERTY_CORRELATION_ID);
+		properties.add(PROPERTY_DESTINATION);
+		properties.add(PROPERTY_REPLY_TO);
+		properties.add(PROPERTY_TIMESTAMP);
+		properties.add(PROPERTY_CATEGORY);
+		properties.add(PROPERTY_INDEXED);
+		properties.add(PROPERTY_PERSISTENT);
+		return properties;
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	@JsonProperty(PROPERTY_CORRELATION_ID)
+	public UUID getCorrelationId() {
+		return getUUIDProperty(properties, PROPERTY_CORRELATION_ID);
+	}
+
+	@JsonProperty(PROPERTY_CORRELATION_ID)
+	public void setCorrelationId(UUID uuid) {
+		setUUIDProperty(properties, PROPERTY_CORRELATION_ID, uuid);
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	public String getDestination() {
+		return getStringProperty(PROPERTY_DESTINATION);
+	}
+
+	public void setDestination(String destination) {
+		setStringProperty(properties, PROPERTY_DESTINATION, destination);
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	@JsonProperty(PROPERTY_REPLY_TO)
+	public String getReplyTo() {
+		return getStringProperty(PROPERTY_DESTINATION);
+	}
+
+	@JsonProperty(PROPERTY_REPLY_TO)
+	public void setReplyTo(String replyTo) {
+		setStringProperty(properties, PROPERTY_DESTINATION, replyTo);
+	}
+
+	@JsonSerialize(include = Inclusion.NON_NULL)
+	public Long getTimestamp() {
+		return JsonUtils.getLongProperty(properties, PROPERTY_TIMESTAMP);
+	}
+
+	public void setTimestamp(Long timestamp) {
+		setLongProperty(properties, PROPERTY_TIMESTAMP, timestamp);
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	public String getCategory() {
+		return getStringProperty(PROPERTY_CATEGORY);
+	}
+
+	public void setCategory(String category) {
+		setStringProperty(properties, PROPERTY_CATEGORY, category);
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	public Boolean isIndexed() {
+		return getBooleanProperty(properties, PROPERTY_INDEXED);
+	}
+
+	public void setIndexed(Boolean indexed) {
+		setBooleanProperty(properties, PROPERTY_INDEXED, indexed);
+	}
+
+	@JsonSerialize(include = NON_NULL)
+	public Boolean isPersistent() {
+		return getBooleanProperty(properties, PROPERTY_INDEXED);
+	}
+
+	public void setPersistent(Boolean persistent) {
+		setBooleanProperty(properties, PROPERTY_INDEXED, persistent);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/User.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/User.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/User.java
new file mode 100755
index 0000000..de85978
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/entities/User.java
@@ -0,0 +1,296 @@
+package org.apache.usergrid.android.sdk.entities;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.getBooleanProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setBooleanProperty;
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty;
+import static com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_NULL;
+
+import java.util.List;
+
+import org.apache.usergrid.android.sdk.UGClient;
+import org.apache.usergrid.android.sdk.response.ApiResponse;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * Models the 'user' entity as a local object.
+ *
+ * @see <a href="http://apigee.com/docs/app-services/content/user-management">User entity documentation</a>
+ */
+public class User extends Entity {
+
+	public final static String ENTITY_TYPE = "user";
+
+	public final static String PROPERTY_USERNAME   = "username";
+	public final static String PROPERTY_EMAIL      = "email";
+	public final static String PROPERTY_NAME       = "name";
+	public final static String PROPERTY_FIRSTNAME  = "firstname";
+	public final static String PROPERTY_MIDDLENAME = "middlename";
+	public final static String PROPERTY_LASTNAME   = "lastname";
+	public final static String PROPERTY_ACTIVATED  = "activated";
+	public final static String PROPERTY_PICTURE    = "picture";
+	public final static String PROPERTY_DISABLED   = "disabled";
+	
+	public static final String OLD_PASSWORD = "oldpassword";
+	public static final String NEW_PASSWORD = "newpassword";
+
+	/**
+	 * Checks if the provided entity 'type' equals 'user'.
+	 *
+	 * @return Boolen true/false
+	 */	
+	public static boolean isSameType(String type) {
+		return type.equals(ENTITY_TYPE);
+	}
+
+	/**
+	 * Default constructor for the User object. Sets the 'type' property to 'user'.
+	 */
+	public User() {
+		setType(ENTITY_TYPE);
+	}
+	
+	/**
+	 * Constructs the User object with a UGClient. 
+	 * Sets the 'type' property to 'user'.
+	 *
+	 * @param  UGClient  an instance of the UGClient class
+	 */
+	public User(UGClient client) {
+		super(client);
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Constructs the User object from an Entity object. Sets the 
+	 * properties of the User identical to Entity, except the 'type' 
+	 * property is set to 'user' no matter what the Entity type is.
+	 *
+	 * @param  entity  an Entity object
+	 */
+	public User(Entity entity) {
+		super(entity.getUGClient());
+		properties = entity.properties;
+		setType(ENTITY_TYPE);
+	}
+
+	/**
+	 * Returns the type property of the User object. Should always
+	 * be 'user' 
+	 *
+	 * @return  the type property of the User object
+	 */
+	@Override
+	@JsonIgnore
+	public String getNativeType() {
+		return ENTITY_TYPE;
+	}
+
+	/**
+	 * Gets the properties already set in User and adds the following 
+	 * user-specific properties: username, email. name, firstname,
+	 * middlename, lastname, activated, picture, disabled.
+	 *
+	 * @return  a List object containing the properties of the User
+	 */
+	@Override
+	@JsonIgnore
+	public List<String> getPropertyNames() {
+		List<String> properties = super.getPropertyNames();
+		properties.add(PROPERTY_USERNAME);
+		properties.add(PROPERTY_EMAIL);
+		properties.add(PROPERTY_NAME);
+		properties.add(PROPERTY_FIRSTNAME);
+		properties.add(PROPERTY_MIDDLENAME);
+		properties.add(PROPERTY_LASTNAME);
+		properties.add(PROPERTY_ACTIVATED);
+		properties.add(PROPERTY_PICTURE);
+		properties.add(PROPERTY_DISABLED);
+		return properties;
+	}
+
+	/**
+	 * Returns the value of the 'username' property currently 
+	 * set in the User object.
+	 *
+	 * @return  the value of the username property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getUsername() {
+		return getStringProperty(PROPERTY_USERNAME);
+	}
+
+	/**
+	 * Sets the username property in the User object.	 
+	 *
+	 * @param  username  the username
+	 */
+	public void setUsername(String username) {
+		setStringProperty(properties, PROPERTY_USERNAME, username);
+	}
+
+	/**
+	 * Returns the value of the 'name' property currently set in 
+	 * the User object.
+	 *
+	 * @return  the value of the name property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getName() {
+		return getStringProperty(PROPERTY_NAME);
+	}
+
+	/**
+	 * Sets the value of the 'name' property in the User object.	 
+	 *
+	 * @param  name  the name of the entity
+	 */
+	public void setName(String name) {
+		setStringProperty(properties, PROPERTY_NAME, name);
+	}
+
+	/**
+	 * Returns the value of the 'email' property currently set in the User object.
+	 *
+	 * @return  the value of the email property
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getEmail() {
+		return getStringProperty(PROPERTY_EMAIL);
+	}
+
+	/**
+	 * Sets the value of the 'email' property in the User object.	 
+	 *
+	 * @param  email  the user's email address
+	 */
+	public void setEmail(String email) {
+		setStringProperty(properties, PROPERTY_EMAIL, email);
+	}
+
+	/**
+	 * Returns the value of the 'activated' property in the User object.
+	 *
+	 * @return  a Boolean true/false
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public Boolean isActivated() {
+		return getBooleanProperty(properties, PROPERTY_ACTIVATED);
+	}
+
+	/**
+	 * Sets the value of the 'activated' property in the User object.	 
+	 *
+	 * @param  activated  boolean whether the user is activated
+	 */
+	public void setActivated(Boolean activated) {
+		setBooleanProperty(properties, PROPERTY_ACTIVATED, activated);
+	}
+
+	/**
+	 * Returns the value of the 'disabled' property in the User object.
+	 *
+	 * @return  a Boolean true/false
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public Boolean isDisabled() {
+		return getBooleanProperty(properties, PROPERTY_DISABLED);
+	}
+
+	/**
+	 * Sets the value of the 'disabled' property in the User object.	 
+	 *
+	 * @param  disabled  Boolean true/false
+	 */
+	public void setDisabled(Boolean disabled) {
+		setBooleanProperty(properties, PROPERTY_DISABLED, disabled);
+	}
+
+	/**
+	 * Returns the value of the 'firstname' property in the User object.
+	 *
+	 * @return  the user's first name
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getFirstname() {
+		return getStringProperty(PROPERTY_FIRSTNAME);
+	}
+
+	/**
+	 * Sets the value of the 'firstname' property in the User object.	 
+	 *
+	 * @param  firstname  the user's first name
+	 */
+	public void setFirstname(String firstname) {
+		setStringProperty(properties, PROPERTY_FIRSTNAME, firstname);
+	}
+
+	/**
+	 * Returns the value of the 'middlename' property in the User object.
+	 *
+	 * @return  the user's middle name
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getMiddlename() {
+		return getStringProperty(PROPERTY_MIDDLENAME);
+	}
+
+	/**
+	 * Sets the value of the 'middlename' property in the User object.	 
+	 *
+	 * @param  middlename  the user's middle name
+	 */
+	public void setMiddlename(String middlename) {
+		setStringProperty(properties, PROPERTY_MIDDLENAME, middlename);
+	}
+
+	/**
+	 * Returns the value of the 'lastname' property in the User object.
+	 *
+	 * @return  the user's last name
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getLastname() {
+		return getStringProperty(PROPERTY_LASTNAME);
+	}
+
+	/**
+	 * Sets the value of the 'lastname' property in the User object.	 
+	 *
+	 * @param  lastname  the user's last name
+	 */
+	public void setLastname(String lastname) {
+		setStringProperty(properties, PROPERTY_LASTNAME, lastname);
+	}
+
+	/**
+	 * Returns the value of the 'picture' property in the User object.
+	 *
+	 * @return  the URL of the user's picture
+	 */
+	@JsonSerialize(include = NON_NULL)
+	public String getPicture() {
+		return getStringProperty(PROPERTY_PICTURE);
+	}
+
+	/**
+	 * Sets the value of the 'picture' property in the User object.	 
+	 *
+	 * @param  picture  the URL of the user's picture
+	 */
+	public void setPicture(String picture) {
+		setStringProperty(properties, PROPERTY_PICTURE, picture);
+	}
+	
+	/**
+	 * Saves the current state of the User object on the server. Any property
+	 * conflicts will overwrite what is on the server.
+	 *
+	 * @return  an ApiResponse object
+	 */
+	public ApiResponse save() {
+		ApiResponse response = super.save();
+		return response;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/exception/ClientException.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/exception/ClientException.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/exception/ClientException.java
new file mode 100755
index 0000000..7e8e72b
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/exception/ClientException.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2012 Usergrid Corporation
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.android.sdk.exception;
+
+/**
+ * Simple wrapper for client exceptions
+ * @author tnine
+ *
+ */
+public class ClientException extends RuntimeException{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public ClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+    
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/21b60593/sdks/android/src/main/java/org/apache/usergrid/android/sdk/response/AggregateCounter.java
----------------------------------------------------------------------
diff --git a/sdks/android/src/main/java/org/apache/usergrid/android/sdk/response/AggregateCounter.java b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/response/AggregateCounter.java
new file mode 100755
index 0000000..54b2582
--- /dev/null
+++ b/sdks/android/src/main/java/org/apache/usergrid/android/sdk/response/AggregateCounter.java
@@ -0,0 +1,39 @@
+package org.apache.usergrid.android.sdk.response;
+
+import static org.apache.usergrid.android.sdk.utils.JsonUtils.toJsonString;
+
+public class AggregateCounter {
+
+	private long timestamp;
+	private long value;
+
+	public AggregateCounter() {
+	}
+
+	public AggregateCounter(long timestamp, long value) {
+		this.timestamp = timestamp;
+		this.value = value;
+	}
+
+	public long getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(long timestamp) {
+		this.timestamp = timestamp;
+	}
+
+	public long getValue() {
+		return value;
+	}
+
+	public void setValue(long value) {
+		this.value = value;
+	}
+
+	@Override
+	public String toString() {
+		return toJsonString(this);
+	}
+
+}